Browse Source

rename module & code review

pull/128/head
MonsieurB 8 years ago
parent
commit
f0926186ec
  1. 10
      base_sms_client/README.rst
  2. 0
      base_sms_client/__init__.py
  3. 20
      base_sms_client/__manifest__.py
  4. 11
      base_sms_client/data/sms_gateway_data.xml
  5. 0
      base_sms_client/i18n/ar.po
  6. 0
      base_sms_client/i18n/ca.po
  7. 0
      base_sms_client/i18n/de.po
  8. 0
      base_sms_client/i18n/es.po
  9. 0
      base_sms_client/i18n/fr.po
  10. 0
      base_sms_client/i18n/pt_BR.po
  11. 0
      base_sms_client/images/client.jpeg
  12. 0
      base_sms_client/images/gateway.jpeg
  13. 0
      base_sms_client/images/gateway_access.jpeg
  14. 0
      base_sms_client/images/send_sms.jpeg
  15. 0
      base_sms_client/images/sms.jpeg
  16. 9
      base_sms_client/models/__init__.py
  17. 7
      base_sms_client/models/server_action.py
  18. 100
      base_sms_client/models/sms_gateway.py
  19. 129
      base_sms_client/models/sms_sms.py
  20. 2
      base_sms_client/models/sms_template.py
  21. 6
      base_sms_client/security/groups.xml
  22. 0
      base_sms_client/security/ir.model.access.csv
  23. 2
      base_sms_client/security/ir.rule.csv
  24. 0
      base_sms_client/static/src/img/icon.png
  25. 19
      base_sms_client/views/server_action_view.xml
  26. 140
      base_sms_client/views/sms_gateway_view.xml
  27. 17
      base_sms_client/views/smstemplate_view.xml
  28. 5
      base_sms_client/wizard/__init__.py
  29. 66
      base_sms_client/wizard/mass_sms.py
  30. 55
      base_sms_client/wizard/mass_sms_view.xml
  31. 1
      oca_dependencies.txt
  32. 4
      ovh_sms_client/README.rst
  33. 0
      ovh_sms_client/__init__.py
  34. 17
      ovh_sms_client/__manifest__.py
  35. 0
      ovh_sms_client/data/keychain.xml
  36. 0
      ovh_sms_client/models/__init__.py
  37. 21
      ovh_sms_client/models/keychain.py
  38. 19
      ovh_sms_client/models/sms_gateway.py
  39. 227
      smsclient_core/models/sms_gateway.py
  40. 8
      smsclient_core/security/groups.xml
  41. 20
      smsclient_core/views/serveraction_view.xml
  42. 146
      smsclient_core/views/sms_gateway_view.xml
  43. 23
      smsclient_core/views/smstemplate_view.xml
  44. 22
      smsclient_core/wizard/__init__.py
  45. 55
      smsclient_core/wizard/mass_sms_view.xml
  46. 45
      smsclient_ovh/models/keychain.py

10
smsclient_core/README.rst → base_sms_client/README.rst

@ -26,19 +26,17 @@ Usage
To use this module, you need to:
* got to partner menu
* select one or multiple partner
* go to more and will found some wizards to send sms
* go to partner menu
* select one or multiple partner
* go to more and will found some wizards to send sms
Bug Tracker
===========
Bugs are tracked on `GitHub Issues <https://github.com/OCA/{project_repo}/issues>`_.
Bugs are tracked on `GitHub Issues <https://github.com/OCA/base_sms_client/issues>`_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us smashing it by providing a detailed and welcomed feedback
`here <https://github.com/OCA/{project_repo}/issues/new?body=module:%20{module_name}%0Aversion:%20{version}%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
Credits
=======

0
smsclient_core/__init__.py → base_sms_client/__init__.py

20
smsclient_core/__manifest__.py → base_sms_client/__manifest__.py

@ -1,18 +1,20 @@
# coding: utf-8
# © 2004-2009 OpenERP SA (<http://openerp.com>)
# Copyright (C) 2015 Sébastien BEAU <sebastien.beau@akretion.com>
# © 2011 SYLEAM (<http://syleam.fr/>)
# © 2013 Julius Network Solutions SARL <contact@julius.fr>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
{
"name": "SMS Client Core",
"name": "Base Sms Client",
"version": "10.0.1.0.0",
"depends": ["base",
"mail",
'license': 'AGPL-3',
"depends": ['mail',
'base_phone',
'keychain',
],
'author': 'Julius Network Solutions,SYLEAM,'
'Odoo Community Association (OCA),Akretion',
'images': [
'images/sms.jpeg',
'images/gateway.jpeg',
@ -20,20 +22,16 @@
'images/client.jpeg',
'images/send_sms.jpeg'
],
"summary": """
Sending SMSs very easily, individually or collectively.
""",
"summary": "Sending SMSs very easily, individually or collectively.",
"website": "http://julius.fr",
"category": "Phone",
"demo": [],
"data": [
"security/groups.xml",
"security/ir.model.access.csv",
"security/ir.rule.csv",
"views/sms_gateway_view.xml",
"views/serveraction_view.xml",
"views/sms_gateway_data.xml",
"views/server_action_view.xml",
"data/sms_gateway_data.xml",
"wizard/mass_sms_view.xml",
"views/smstemplate_view.xml"
],

11
smsclient_core/views/sms_gateway_data.xml → base_sms_client/data/sms_gateway_data.xml

@ -5,10 +5,11 @@
<field name="interval_number">1</field>
<field name="interval_type">minutes</field>
<field name="numbercall">-1</field>
<field eval="False" name="doall"/>
<field eval="'sms.gateway'" name="model"/>
<field eval="'_run_send_sms'" name="function"/>
<field eval="'()'" name="args"/>
<field name="active" eval="False"/>
<field name="doall">False</field>
<field name="model">sms.gateway</field>
<field name="function">_run_send_sms</field>
<field name="args">()</field>
<field name="active">False</field>
</record>
</odoo>

0
smsclient_core/i18n/ar.po → base_sms_client/i18n/ar.po

0
smsclient_core/i18n/ca.po → base_sms_client/i18n/ca.po

0
smsclient_core/i18n/de.po → base_sms_client/i18n/de.po

0
smsclient_core/i18n/es.po → base_sms_client/i18n/es.po

0
smsclient_core/i18n/fr.po → base_sms_client/i18n/fr.po

0
smsclient_core/i18n/pt_BR.po → base_sms_client/i18n/pt_BR.po

0
smsclient_core/images/client.jpeg → base_sms_client/images/client.jpeg

Before

Width: 1301  |  Height: 359  |  Size: 43 KiB

After

Width: 1301  |  Height: 359  |  Size: 43 KiB

0
smsclient_core/images/gateway.jpeg → base_sms_client/images/gateway.jpeg

Before

Width: 1301  |  Height: 418  |  Size: 59 KiB

After

Width: 1301  |  Height: 418  |  Size: 59 KiB

0
smsclient_core/images/gateway_access.jpeg → base_sms_client/images/gateway_access.jpeg

Before

Width: 1301  |  Height: 413  |  Size: 56 KiB

After

Width: 1301  |  Height: 413  |  Size: 56 KiB

0
smsclient_core/images/send_sms.jpeg → base_sms_client/images/send_sms.jpeg

Before

Width: 897  |  Height: 480  |  Size: 23 KiB

After

Width: 897  |  Height: 480  |  Size: 23 KiB

0
smsclient_core/images/sms.jpeg → base_sms_client/images/sms.jpeg

Before

Width: 1301  |  Height: 359  |  Size: 43 KiB

After

Width: 1301  |  Height: 359  |  Size: 43 KiB

9
base_sms_client/models/__init__.py

@ -0,0 +1,9 @@
# -*- coding: utf-8 -*-
# Copyright (C) 2013 Julius Network Solutions SARL <contact@julius.fr>
# Author: Sébastien BEAU <sebastien.beau@akretion.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from . import sms_gateway
from . import server_action
from . import sms_template
from . import sms_sms

7
smsclient_core/models/serveraction.py → base_sms_client/models/server_action.py

@ -4,14 +4,9 @@
# Copyright (C) 2015 Valentin Chemiere <valentin.chemiere@akretion.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
import logging
from odoo import models, fields
_logger = logging.getLogger('gateway')
class ServerAction(models.Model):
"""
Possibility to specify the SMS Gateway when configure this server action
@ -24,7 +19,7 @@ class ServerAction(models.Model):
" the invoice model and `object.invoice_address_id.mobile` "
"will be the field providing the correct mobile number.")
sms = fields.Char(string='SMS', size=160, translate=True)
sms_server = fields.Many2one(
sms_server_id = fields.Many2one(
comodel_name='sms.gateway', string='SMS Server',
help='Select the SMS Gateway configuration to use with this action.')
sms_template_id = fields.Many2one(

100
base_sms_client/models/sms_gateway.py

@ -0,0 +1,100 @@
# coding: utf-8
# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>).
# Copyright (C) 2011 SYLEAM (<http://syleam.fr/>)
# Copyright (C) 2013 Julius Network Solutions SARL <contact@julius.fr>
# Copyright (C) 2015 Valentin Chemiere <valentin.chemiere@akretion.com>
# Copyright (C) 2015 Sébastien BEAU <sebastien.beau@akretion.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import models, fields, api
PRIORITY_LIST = [
('0', '0'),
('1', '1'),
('2', '2'),
('3', '3')
]
CLASSES_LIST = [
('0', 'Flash'),
('1', 'Phone display'),
('2', 'SIM'),
('3', 'Toolkit')
]
class SmsAbstract(models.AbstractModel):
_name = 'sms.abstract'
_description = 'SMS Abstract Model'
code = fields.Char('Verification Code')
body = fields.Text(
string='Message',
help="The message text that will be send along with the"
" email which is send through this server.")
classes = fields.Selection(
selection=CLASSES_LIST, string='Class',
default='1',
help='The SMS class')
deferred = fields.Integer(
help='The time -in minute(s)- to wait before sending the message.')
priority = fields.Selection(
selection=PRIORITY_LIST, string='Priority', default='3',
help='The priority of the message')
coding = fields.Selection(selection=[
('1', '7 bit'),
('2', 'Unicode')
], string='Coding',
help='The SMS coding: 1 for 7 bit (160 chracters max'
'length) or 2 for unicode (70 characters max'
'length)',
default='1'
)
tag = fields.Char('Tag', help='an optional tag')
nostop = fields.Boolean(
default=True,
help='Do not display STOP clause in the message, this requires that '
'this is not an advertising message.')
validity = fields.Integer(
default=10,
help="The maximum time - in minute(s) - before the message "
"is dropped.")
char_limit = fields.Integer(string='Character Limit', default=160)
default_gateway = fields.Boolean()
company_id = fields.Many2one(comodel_name='res.company')
class SmsGateway(models.Model):
_name = 'sms.gateway'
_description = 'SMS Client'
_inherit = 'sms.abstract'
name = fields.Char(string='Gateway Name', required=True)
from_provider = fields.Char(string="From")
method = fields.Selection(string='API Method', selection=[])
url = fields.Char(
string='Gateway URL', help='Base url for message')
state = fields.Selection(selection=[
('new', 'Not Verified'),
('waiting', 'Waiting for Verification'),
('confirm', 'Verified'),
], string='Gateway Status', index=True, readonly=True, default='new')
user_ids = fields.Many2many(
comodel_name='res.users',
string='Users Allowed to use the gateway')
@api.multi
def _check_permissions(self):
self.ensure_one()
if self.env.uid not in self.sudo().user_ids.ids:
return False
return True
@api.model
def _run_send_sms(self, domain=None):
if domain is None:
domain = []
domain.append(('state', '=', 'draft'))
sms = self.env['sms.sms'].search(domain)
return sms.send()

129
base_sms_client/models/sms_sms.py

@ -0,0 +1,129 @@
# coding: utf-8
# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>).
# Copyright (C) 2011 SYLEAM (<http://syleam.fr/>)
# Copyright (C) 2013 Julius Network Solutions SARL <contact@julius.fr>
# Copyright (C) 2015 Valentin Chemiere <valentin.chemiere@akretion.com>
# Copyright (C) 2015 Sébastien BEAU <sebastien.beau@akretion.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import models, fields, api, _
import logging
_logger = logging.getLogger(__name__)
class SmsSms(models.Model):
_name = 'sms.sms'
_description = 'SMS'
_rec_name = 'mobile'
_inherit = 'sms.abstract'
message = fields.Text(
size=256,
required=True,
readonly=True,
states={'draft': [('readonly', False)]})
mobile = fields.Char(
required=True,
readonly=True,
states={'draft': [('readonly', False)]})
gateway_id = fields.Many2one(
comodel_name='sms.gateway',
string='SMS Gateway',
readonly=True,
states={'draft': [('readonly', False)]})
partner_id = fields.Many2one(
'res.partner',
readonly=True,
states={'draft': [('readonly', False)]},
string='Partner')
state = fields.Selection(selection=[
('draft', 'Queued'),
('sent', 'Sent'),
('cancel', 'Cancel'),
('error', 'Error'),
], string='Message Status',
readonly=True,
default='draft')
error = fields.Text(
string='Last Error',
size=256,
readonly=True,
states={'draft': [('readonly', False)]})
@api.onchange('partner_id')
def onchange_partner_id(self):
self.mobile = self.partner_id.mobile
# commit is use to not loose each sms state with orm rollback
@api.multi
def _check_gateway_method(self):
self.ensure_one()
if self.gateway_id.method:
return True
else:
self.write({
'state': 'error',
'error': _("No method gateway selected ")})
self._cr.commit()
return False
@api.multi
def _check_gateway_permission(self):
self.ensure_one()
if self.gateway_id._check_permissions():
return True
else:
self.write(
{'error': 'no permission on gateway', 'state': 'error'})
self._cr.commit()
return False
@api.multi
def _check_sms_length(self):
self.ensure_one()
if len(self.message) <= self.gateway_id.char_limit:
return True
else:
self.write({
'state': 'error',
'error': _("Size of SMS should not be more than %s "
"characters ") % self.sms.gateway_id.char_limit
})
self._cr.commit()
return False
@api.multi
def send(self):
allsend_ok = True
for sms in self:
sms_check = True
if not sms._check_gateway_method():
allsend_ok = False
sms_check = False
continue
if not sms.gateway_id._check_permissions():
allsend_ok = False
sms_check = False
continue
if not sms._check_sms_length():
allsend_ok = False
sms_check = False
continue
if sms_check:
try:
with sms._cr.savepoint():
getattr(sms, "_send_%s" % sms.gateway_id.method)()
sms.write({'state': 'sent', 'error': ''})
except Exception as e:
_logger.error('Failed to send sms %s', e)
sms.write({'error': e, 'state': 'error'})
sms._cr.commit()
return allsend_ok
@api.multi
def cancel(self):
self.write({'state': 'cancel'})
@api.multi
def retry(self):
self.write({'state': 'draft'})

2
smsclient_core/models/smstemplate.py → base_sms_client/models/sms_template.py

@ -8,7 +8,7 @@
from odoo import models, fields
class mail_template(models.Model):
class MailTemplate(models.Model):
_inherit = "mail.template"
sms_template = fields.Boolean('SMS Template')

6
base_sms_client/security/groups.xml

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<odoo>
<record id="group_sms_user" model="res.groups">
<field name="name">SMS / User</field>
</record>
</odoo>

0
smsclient_core/security/ir.model.access.csv → base_sms_client/security/ir.model.access.csv

2
smsclient_core/security/ir.rule.csv → base_sms_client/security/ir.rule.csv

@ -1,4 +1,4 @@
id,name,model_id:id,groups:id,perm_read,perm_write,perm_create,perm_unlink,domain_force
edit_access_sms,Edit Access Sms,model_sms_sms,,True,True,True,True,"[('company_id','=', user.company_id.id)]"
edit_access_sms_gateway,Edit Access Sms Gateway,model_sms_gateway,,False,True,True,True,"[('company_id','=', user.company_id.id)]"
read_access_sms_gateway,Read Access Sms Gateway,model_sms_gateway,,True,False,False,False,"['|', '|', ('company_id','=', user.company_id.id),('company_id','child_of',[user.company_id.id]),('company_id','=',user.company_id.parent_id.id)]"
edit_access_sms,Edit Access Sms,model_sms_sms,,True,True,True,True,"[('company_id','=', user.company_id.id)]"

0
smsclient_core/static/src/img/icon.png → base_sms_client/static/src/img/icon.png

Before

Width: 224  |  Height: 225  |  Size: 34 KiB

After

Width: 224  |  Height: 225  |  Size: 34 KiB

19
base_sms_client/views/server_action_view.xml

@ -0,0 +1,19 @@
<?xml version="1.0"?>
<odoo>
<record model="ir.ui.view" id="view_server_statistics_graph">
<field name="model">ir.actions.server</field>
<field name="inherit_id" ref="base.view_server_action_form"/>
<field name="arch" type="xml">
<page name="code" position="after" autofocus="autofocus">
<page string="SMS" name="sms" attrs="{'invisible': [('state', '!=', 'sms')]}">
<group>
<field name="sms"/>
<field name="mobile"/>
<field name="sms_server_id" invisible="1"/>
<field name="sms_template_id" domain="[('sms_template','=',True)]" attrs="{'required':[('state','=','sms')]}"/>
</group>
</page>
</page>
</field>
</record>
</odoo>

140
base_sms_client/views/sms_gateway_view.xml

@ -0,0 +1,140 @@
<?xml version="1.0"?>
<odoo>
<record model="ir.ui.view" id="sms_gateway_form">
<field name="model">sms.gateway</field>
<field name="priority" eval="8"/>
<field name="arch" type="xml">
<form string="SMS Gateway">
<sheet>
<group col="2">
<h1><field name="name" nolabel="1" placeholder="Name" colspan="2"/></h1>
<field name="method" nolabel="1" placeholder="Method" colspan="2"/>
<field name="default_gateway"/>
<field name="company_id" groups="base.group_multi_company"/>
</group>
<notebook colspan="4">
<page string="General">
<group col="4">
<field name="state"/>
<field name="from_provider"/>
<field name="url"/>
</group>
</page>
<page string="Permission">
<separator string="Access Permission"
colspan="4" />
<field name="user_ids" colspan="4" nolabel="1"/>
</page>
<page string="Additional option">
<group>
<group>
<field name="validity" />
<field name="classes"/>
<field name="deferred" />
<field name="nostop" />
</group>
<group>
<field name="priority" />
<field name="coding"/>
<field name="tag"/>
<field name="char_limit"/>
</group>
</group>
</page>
</notebook>
</sheet>
</form>
</field>
</record>
<record model="ir.ui.view" id="sms_gateway_tree">
<field name="model">sms.gateway</field>
<field name="priority" eval="8"/>
<field name="arch" type="xml">
<tree string="SMS Gateways">
<field name="name"/>
<field name="method"/>
</tree>
</field>
</record>
<record model="ir.actions.act_window" id="action_sms_gateway_tree">
<field name="name">SMS Gateway</field>
<field name="res_model">sms.gateway</field>
<field name="view_type">form</field>
<field name="view_mode">form,tree</field>
<field name="view_id" ref="sms_gateway_tree" />
</record>
<menuitem name="SMS Gateway"
id="menu_gateway_administration_sms_server"
sequence="100"
parent="base_phone.menu_config_phone"
action="action_sms_gateway_tree"/>
<record model="ir.ui.view" id="sms_sms_tree">
<field name="model">sms.sms</field>
<field name="arch" type="xml">
<tree string="Sms">
<field name="create_date"/>
<field name="mobile"/>
<field name="message"/>
<field name="state"/>
<field name="gateway_id"/>
<button string="Send" states="draft" type="object" name="send"/>
<button string="Retry" states="error" type="object" name="retry"/>
<button string="Cancel" states="draft,error" type="object" name="cancel"/>
</tree>
</field>
</record>
<record model="ir.ui.view" id="sms_sms_form">
<field name="model">sms.sms</field>
<field name="arch" type="xml">
<form string="Sms">
<header>
<button string="Send" states="draft" type="object" name="send"/>
<button string="Retry" states="error" type="object" name="retry"/>
<button string="Cancel" states="draft,error" type="object" name="cancel"/>
<field name="state" widget="statusbar" statusbar_visible="draft,send"/>
</header>
<sheet>
<label for="partner_id" class="oe_edit_only"/>
<h1><field name="partner_id"/></h1>
<label for="mobile" class="oe_edit_only"/>
<h1><field name="mobile"/></h1>
<group col="4">
<field name="create_date" readonly="True"/>
<field name="gateway_id" colspan="2"/>
<field name="company_id" groups="base.group_multi_company"/>
<separator string="SMS Message" colspan="4"/>
<field name="message" colspan="4" nolabel="1"/>
<separator string="Last Error" colspan="4"/>
<field name="error" colspan="4" nolabel="1"/>
</group>
</sheet>
</form>
</field>
</record>
<record model="ir.actions.act_window" id="action_sms_sms_tree">
<field name="name">Sms</field>
<field name="res_model">sms.sms</field>
<field name="view_type">form</field>
<field name="view_mode">form,tree</field>
<field name="view_id" ref="sms_sms_tree" />
</record>
<menuitem name="SMS Message"
id="menu_gateway_administration_sms"
sequence="110"
parent="base_phone.menu_config_phone"
action="action_sms_sms_tree"/>
<act_window context="{'gateway_id': active_id}"
domain="[('gateway_id', '=', active_id)]"
id="act_sms_gateway_2_sms"
name="Sms Message"
res_model="sms.sms"
src_model="sms.gateway"/>
</odoo>

17
base_sms_client/views/smstemplate_view.xml

@ -0,0 +1,17 @@
<?xml version="1.0"?>
<odoo>
<record model="ir.ui.view" id="email_template_form">
<field name="name">mail.template.form</field>
<field name="model">mail.template</field>
<field name="inherit_id" ref="mail.email_template_form"/>
<field name="arch" type="xml">
<field name="email_to" position="after">
<field name="mobile_to"/>
</field>
<field name="lang" position="before">
<field name="sms_template"/>
<field name="gateway_id"/>
</field>
</field>
</record>
</odoo>

5
smsclient_core/models/__init__.py → base_sms_client/wizard/__init__.py

@ -1,7 +1,6 @@
# -*- coding: utf-8 -*-
# Copyright (C) 2013 Julius Network Solutions SARL <contact@julius.fr>
# Author: Sébastien BEAU <sebastien.beau@akretion.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from . import sms_gateway
from . import serveraction
from . import smstemplate
from . import mass_sms

66
smsclient_core/wizard/mass_sms.py → base_sms_client/wizard/mass_sms.py

@ -7,8 +7,8 @@
from odoo import models, fields, api
class WizardSendSms(models.TransientModel):
_name = 'wizard.send.sms'
class WizardMassSms(models.TransientModel):
_name = 'wizard.mass.sms'
@api.model
def _default_get_gateway(self):
@ -19,6 +19,37 @@ class WizardSendSms(models.TransientModel):
if self._context.get('active_model') == 'res.partner':
return self._context.get('active_ids')
gateway_id = fields.Many2one(
'sms.gateway',
required=True,
default=_default_get_gateway)
message = fields.Text(required=True)
validity = fields.Integer(
help='The maximum time -in minute(s)- before the message is dropped')
classes = fields.Selection([
('0', 'Flash'),
('1', 'Phone display'),
('2', 'SIM'),
('3', 'Toolkit'),
], help='The sms class: flash(0),phone display(1),SIM(2),toolkit(3)')
deferred = fields.Integer(
help='The time -in minute(s)- to wait before sending the message')
priority = fields.Selection([
('0', '0'),
('1', '1'),
('2', '2'),
('3', '3')
], help='The priority of the message')
coding = fields.Selection([
('1', '7 bit'),
('2', 'Unicode')
], help='The sms coding: 1 for 7 bit or 2 for unicode')
tag = fields.Char(size=256, help='An optional tag')
nostop = fields.Boolean(
help='Do not display STOP clause in the message, this requires that '
'this is not an advertising message')
partner_ids = fields.Many2many('res.partner', default=_default_get_partner)
@api.onchange('gateway_id')
def onchange_gateway_mass(self):
for key in ['validity', 'classes', 'deferred', 'priority',
@ -49,34 +80,3 @@ class WizardSendSms(models.TransientModel):
for partner in partner_obj.browse(self._context.get('active_ids')):
vals = self._prepare_sms_vals(partner)
sms_obj.create(vals)
gateway_id = fields.Many2one(
'sms.gateway',
required=True,
default=_default_get_gateway)
message = fields.Text(required=True)
validity = fields.Integer(
help='The maximum time -in minute(s)- before the message is dropped')
classes = fields.Selection([
('0', 'Flash'),
('1', 'Phone display'),
('2', 'SIM'),
('3', 'Toolkit'),
], help='The sms class: flash(0),phone display(1),SIM(2),toolkit(3)')
deferred = fields.Integer(
help='The time -in minute(s)- to wait before sending the message')
priority = fields.Selection([
('0', '0'),
('1', '1'),
('2', '2'),
('3', '3')
], help='The priority of the message')
coding = fields.Selection([
('1', '7 bit'),
('2', 'Unicode')
], help='The sms coding: 1 for 7 bit or 2 for unicode')
tag = fields.Char(size=256, help='An optional tag')
nostop = fields.Boolean(
help='Do not display STOP clause in the message, this requires that '
'this is not an advertising message')
partner_ids = fields.Many2many('res.partner', default=_default_get_partner)

55
base_sms_client/wizard/mass_sms_view.xml

@ -0,0 +1,55 @@
<?xml version="1.0"?>
<odoo>
<record model="ir.ui.view" id="view_wizard_mass_sms">
<field name="model">wizard.mass.sms</field>
<field name="arch" type="xml">
<form string="SMS Gateway - Sens SMS" version="7.0">
<group string="Gateway" colspan="4">
<field name="gateway_id"/>
</group>
<notebook>
<page string="Message">
<field name="message" colspan="4" nolabel="1"/>
<!-- TODO limit to 10 the number of partner to show -->
<field name="partner_ids" colspan="4" nolabel="1">
<tree options="{'limit': 10}">
<field name="name"/>
<field name="mobile"/>
</tree>
</field>
</page>
<page string="Additional option">
<group>
<group>
<field name="validity"/>
<field name="classes"/>
<field name="deferred"/>
<field name="nostop"/>
</group>
<group>
<field name="priority"/>
<field name="coding"/>
<field name="tag"/>
</group>
</group>
</page>
</notebook>
<footer>
<button string="Send SMS" name="send" type="object"
class="oe_highlight"/>
or
<button string="Cancel" class="oe_link"
special="cancel"/>
</footer>
</form>
</field>
</record>
<act_window name="Send an SMS"
res_model="wizard.mass.sms"
src_model="res.partner"
view_mode="form"
target="new"
key2="client_action_multi"
id="action_wizard_mass_sms"/>
</odoo>

1
oca_dependencies.txt

@ -0,0 +1 @@
server-tools

4
smsclient_ovh/README.rst → ovh_sms_client/README.rst

@ -23,11 +23,9 @@ For further information, please visit:
Bug Tracker
===========
Bugs are tracked on `GitHub Issues <https://github.com/OCA/{project_repo}/issues>`_.
Bugs are tracked on `GitHub Issues <https://github.com/OCA/ovh_sms_client/issues>`_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us smashing it by providing a detailed and welcomed feedback
`here <https://github.com/OCA/{project_repo}/issues/new?body=module:%20{module_name}%0Aversion:%20{version}%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
Credits
=======

0
smsclient_ovh/__init__.py → ovh_sms_client/__init__.py

17
smsclient_ovh/__manifest__.py → ovh_sms_client/__manifest__.py

@ -3,15 +3,15 @@
# Copyright (C) 2015 Sébastien BEAU <sebastien.beau@akretion.com>
{
'name': 'SMS Client OVH',
'name': 'OVH SMS Client',
'version': '10.0.1.0.0',
'depends': ['base',
'mail',
'smsclient_core',
'license': 'AGPL-3',
'depends': ['mail',
'base_sms_client',
'base_suspend_security',
'keychain',
],
'author': 'Julius Network Solutions,SYLEAM,OpenERP SA,'
'author': 'Julius Network Solutions,SYLEAM,'
'Odoo Community Association (OCA),Akretion',
'images': [
'images/sms.jpeg',
@ -22,11 +22,6 @@
],
'website': 'http://julius.fr',
'category': 'Tools',
'demo': [],
'data': [
],
'active': False,
'data': ['data/keychain.xml'],
'installable': True,
}
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

0
smsclient_ovh/data/keychain.xml → ovh_sms_client/data/keychain.xml

0
smsclient_ovh/models/__init__.py → ovh_sms_client/models/__init__.py

21
ovh_sms_client/models/keychain.py

@ -0,0 +1,21 @@
# coding: utf-8
# Copyright (C) 2015 Sébastien BEAU <sebastien.beau@akretion.com>
# Valentin CHEMIERE <valentin.chemiere@akretion.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import models, fields
OVH_KEYCHAIN_NAMESPACE = 'ovh_provider'
class Keychain(models.Model):
_inherit = 'keychain.account'
namespace = fields.Selection(
selection_add=[(OVH_KEYCHAIN_NAMESPACE, 'Ovh_sms')])
def _ovh_provider_init_data(self):
return {'sms_account': ""}
def _ovh_provider_validate_data(self, data):
return True

19
smsclient_ovh/models/sms_gateway.py → ovh_sms_client/models/sms_gateway.py

@ -3,10 +3,10 @@
# Valentin CHEMIERE <valentin.chemiere@akretion.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import api, models
from odoo import api, models, fields
from ..models.keychain import OVH_KEYCHAIN_NAMESPACE
import requests
import logging
import json
_logger = logging.getLogger(__name__)
@ -14,22 +14,18 @@ _logger = logging.getLogger(__name__)
class SmsClient(models.Model):
_inherit = "sms.gateway"
@api.model
def get_method(self):
method = super(SmsClient, self).get_method()
method.append(('http_ovh', 'OVH HTTP'), )
return method
method = fields.Selection(selection_add=[('http_ovh', 'OVH HTTP')])
@api.multi
def _provider_get_provider_conf(self):
for rec in self:
keychain = rec.env['keychain.account']
if rec._check_permissions:
if rec._check_permissions():
retrieve = keychain.suspend_security().retrieve
else:
retrieve = keychain.retrieve
accounts = retrieve(
[['namespace', '=', 'ovh_provider']])
[['namespace', '=', OVH_KEYCHAIN_NAMESPACE]])
return accounts[0]
@ -40,9 +36,9 @@ class SmsSms(models.Model):
def _prepare_http_ovh(self):
keychain_account = self.gateway_id._provider_get_provider_conf()
keychain_json = json.loads(keychain_account['data'])
keychain_data = keychain_account.get_data()
params = {
'smsAccount': keychain_json['sms_account'],
'smsAccount': keychain_data['sms_account'],
'login': keychain_account['login'],
'password': keychain_account.get_password(),
'from': self.gateway_id.from_provider,
@ -78,7 +74,6 @@ class SmsSms(models.Model):
'smsAccount': '*****',
'login': '*****',
})
print params
_logger.debug("Call OVH API : %s params %s",
params['url'], params)
response = r.text

227
smsclient_core/models/sms_gateway.py

@ -1,227 +0,0 @@
# coding: utf-8
# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>).
# Copyright (C) 2011 SYLEAM (<http://syleam.fr/>)
# Copyright (C) 2013 Julius Network Solutions SARL <contact@julius.fr>
# Copyright (C) 2015 Valentin Chemiere <valentin.chemiere@akretion.com>
# Copyright (C) 2015 Sébastien BEAU <sebastien.beau@akretion.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
import logging
from odoo import models, fields, api, _
from odoo.exceptions import UserError
_logger = logging.getLogger(__name__)
PRIORITY_LIST = [
('0', '0'),
('1', '1'),
('2', '2'),
('3', '3')
]
CLASSES_LIST = [
('0', 'Flash'),
('1', 'Phone display'),
('2', 'SIM'),
('3', 'Toolkit')
]
class SMSClient(models.Model):
_name = 'sms.gateway'
_description = 'SMS Client'
@api.model
def get_method(self):
return []
name = fields.Char(string='Gateway Name', required=True)
from_provider = fields.Char(string="From")
method = fields.Selection(
string='API Method',
selection='get_method')
url = fields.Char(
string='Gateway URL', help='Base url for message')
state = fields.Selection(selection=[
('new', 'Not Verified'),
('waiting', 'Waiting for Verification'),
('confirm', 'Verified'),
], string='Gateway Status', index=True, readonly=True, default='new')
user_ids = fields.Many2many(
comodel_name='res.users',
string='Users Allowed')
code = fields.Char('Verification Code')
body = fields.Text(
string='Message',
help="The message text that will be send along with the"
" email which is send through this server.")
validity = fields.Integer(
default=10,
help="The maximum time - in minute(s) - before the message "
"is dropped.")
classes = fields.Selection(
selection=CLASSES_LIST, string='Class',
default='1',
help='The SMS class: flash(0),phone display(1),SIM(2),toolkit(3)')
deferred = fields.Integer(
default=0,
help='The time -in minute(s)- to wait before sending the message.')
deferred_visible = fields.Boolean(default=False)
priority = fields.Selection(
selection=PRIORITY_LIST, string='Priority', default='3',
help='The priority of the message')
coding = fields.Selection(selection=[
('1', '7 bit'),
('2', 'Unicode')
], string='Coding',
help='The SMS coding: 1 for 7 bit (160 chracters max'
'lenght) or 2 for unicode (70 characters max'
'lenght)',
default='1'
)
tag = fields.Char('Tag', help='an optional tag')
nostop = fields.Boolean(
default=True,
help='Do not display STOP clause in the message, this requires that '
'this is not an advertising message.')
char_limit = fields.Boolean('Character Limit', default=True)
default_gateway = fields.Boolean(default=False)
company_id = fields.Many2one(comodel_name='res.company')
@api.multi
def _check_permissions(self):
self.ensure_one()
if self.env.uid not in self.sudo().user_ids.ids:
return False
return True
@api.model
def _run_send_sms(self, domain=None):
if domain is None:
domain = []
domain.append(('state', '=', 'draft'))
sms = self.env['sms.sms'].search(domain)
return sms.send()
class SmsSms(models.Model):
_name = 'sms.sms'
_description = 'SMS'
_rec_name = 'mobile'
message = fields.Text(
size=256,
required=True,
readonly=True,
states={'draft': [('readonly', False)]})
mobile = fields.Char(
required=True,
readonly=True,
states={'draft': [('readonly', False)]})
gateway_id = fields.Many2one(
comodel_name='sms.gateway',
string='SMS Gateway',
readonly=True,
states={'draft': [('readonly', False)]})
state = fields.Selection(selection=[
('draft', 'Queued'),
('sent', 'Sent'),
('cancel', 'Cancel'),
('error', 'Error'),
], string='Message Status',
readonly=True,
default='draft')
error = fields.Text(
string='Last Error',
size=256,
readonly=True,
states={'draft': [('readonly', False)]})
validity = fields.Integer(
string='Validity',
readonly=True,
states={'draft': [('readonly', False)]},
help='The maximum time -in minute(s)- before the message is dropped.')
classes = fields.Selection(
selection=CLASSES_LIST,
readonly=True,
states={'draft': [('readonly', False)]},
help='The sms class: flash(0), phone display(1), SIM(2), toolkit(3)')
deferred = fields.Integer(
readonly=True,
states={'draft': [('readonly', False)]},
help='The time -in minute(s)- to wait before sending the message.')
priority = fields.Selection(
readonly=True,
states={'draft': [('readonly', False)]},
selection=PRIORITY_LIST,
help='The priority of the message ')
coding = fields.Selection([
('1', '7 bit'),
('2', 'Unicode')
], readonly=True,
states={'draft': [('readonly', False)]},
help='The sms coding: 1 for 7 bit or 2 for unicode')
tag = fields.Char(
size=256,
readonly=True,
states={'draft': [('readonly', False)]},
help='An optional tag')
nostop = fields.Boolean(
string='NoStop',
readonly=True,
states={'draft': [('readonly', False)]},
help='Do not display STOP clause in the message, this requires that'
'this is not an advertising message.')
partner_id = fields.Many2one(
'res.partner',
readonly=True,
states={'draft': [('readonly', False)]},
string='Partner')
company_id = fields.Many2one(
comodel_name='res.company',
readonly=True,
states={'draft': [('readonly', False)]})
@api.model
def _convert_to_e164(self, erp_number):
to_dial_number = erp_number.replace(u'\xa0', u' ')
return to_dial_number
@api.onchange('partner_id')
def onchange_partner_id(self):
self.mobile = self.partner_id.mobile
@api.multi
def send(self):
for sms in self:
if not sms.gateway_id._check_permissions():
sms.write(
{'error': 'no permission on gateway', 'state': 'error'})
sms._cr.commit()
return False
if sms.gateway_id.char_limit and len(sms.message) > 160:
sms.write({
'state': 'error',
'error': _('Size of SMS should not be more then 160 char'),
})
if not hasattr(sms, "_send_%s" % sms.gateway_id.method):
#may not exist the gateway
raise UserError(_("No method gateway selected"))
else:
try:
with sms._cr.savepoint():
getattr(sms, "_send_%s" % sms.gateway_id.method)()
sms.write({'state': 'sent', 'error': ''})
except Exception, e:
_logger.error('Failed to send sms %s', e)
sms.write({'error': e, 'state': 'error'})
sms._cr.commit()
return True
@api.multi
def cancel(self):
self.write({'state': 'cancel'})
@api.multi
def retry(self):
self.write({'state': 'draft'})

8
smsclient_core/security/groups.xml

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<openerp>
<data>
<record id="group_sms_user" model="res.groups">
<field name="name">SMS / User</field>
</record>
</data>
</openerp>

20
smsclient_core/views/serveraction_view.xml

@ -1,20 +0,0 @@
<?xml version="1.0"?>
<odoo>
<record model="ir.ui.view" id="view_server_statistics_graph">
<field name="name">ir.actions.server.form.inherit</field>
<field name="model">ir.actions.server</field>
<field name="inherit_id" ref="base.view_server_action_form"/>
<field name="arch" type="xml">
<page name="code" position="after" autofocus="autofocus">
<page string="SMS" name="sms" attrs="{'invisible': [('state', '!=', 'sms')]}">
<group>
<field name="sms"/>
<field name="mobile"/>
<field name="sms_server" invisible="1"/>
<field name="sms_template_id" domain="[('sms_template','=',True)]" attrs="{'required':[('state','=','sms')]}"/>
</group>
</page>
</page>
</field>
</record>
</odoo>

146
smsclient_core/views/sms_gateway_view.xml

@ -1,146 +0,0 @@
<?xml version="1.0"?>
<odoo>
<!-- ************************************************************** -->
<!-- ** SMS Gateway list ****************************************** -->
<!-- ************************************************************** -->
<record model="ir.ui.view" id="sms_gateway_form">
<field name="model">sms.gateway</field>
<field name="priority" eval="8"/>
<field name="arch" type="xml">
<form string="SMS Gateway">
<sheet>
<group col="2">
<h1><field name="name" nolabel="1" placeholder="Name" colspan="2"/></h1>
<field name="method" nolabel="1" placeholder="Method" colspan="2"/>
<field name="default_gateway"/>
<field name="company_id" groups="base.group_multi_company"/>
</group>
<notebook colspan="4">
<page string="General">
<group col="4">
<field name="state"/>
<field name="from_provider"/>
<field name="url"/>
</group>
</page>
<page string="Permission">
<separator string="Access Permission"
colspan="4" />
<field name="user_ids" colspan="4" nolabel="1"/>
</page>
<page string="Additional option">
<group>
<group>
<field name="validity" />
<field name="classes"/>
<field name="deferred" />
<field name="nostop" />
</group>
<group>
<field name="priority" />
<field name="coding"/>
<field name="tag"/>
<field name="char_limit"/>
</group>
</group>
</page>
</notebook>
</sheet>
</form>
</field>
</record>
<record model="ir.ui.view" id="sms_gateway_tree">
<field name="model">sms.gateway</field>
<field name="priority" eval="8"/>
<field name="arch" type="xml">
<tree string="SMS Gateways">
<field name="name"/>
<field name="method"/>
</tree>
</field>
</record>
<record model="ir.actions.act_window" id="action_sms_gateway_tree">
<field name="name">SMS Gateway</field>
<field name="res_model">sms.gateway</field>
<field name="view_type">form</field>
<field name="view_mode">form,tree</field>
<field name="view_id" ref="sms_gateway_tree" />
</record>
<menuitem name="SMS Gateway"
id="menu_gateway_administration_sms_server"
sequence="100"
parent="base_phone.menu_config_phone"
action="action_sms_gateway_tree"/>
<record model="ir.ui.view" id="sms_sms_tree">
<field name="model">sms.sms</field>
<field name="arch" type="xml">
<tree string="Sms">
<field name="create_date"/>
<field name="mobile"/>
<field name="message"/>
<field name="state"/>
<field name="gateway_id"/>
<button string="Send" states="draft" type="object" name="send" icon="gtk-ok"/>
<button string="Retry" states="error" type="object" name="retry" icon="gtk-redo"/>
<button string="Cancel" states="draft,error" type="object" name="cancel" icon="terp-gtk-stop"/>
<field name="state"/>
</tree>
</field>
</record>
<record model="ir.ui.view" id="sms_sms_form">
<field name="model">sms.sms</field>
<field name="arch" type="xml">
<form string="Sms">
<header>
<button string="Send" states="draft" type="object" name="send"/>
<button string="Retry" states="error" type="object" name="retry"/>
<button string="Cancel" states="draft,error" type="object" name="cancel"/>
<field name="state" widget="statusbar" statusbar_visible="draft,send"/>
</header>
<sheet>
<label for="partner_id" class="oe_edit_only"/>
<h1><field name="partner_id"/></h1>
<label for="mobile" class="oe_edit_only"/>
<h1><field name="mobile"/></h1>
<group>
<field name="create_date" readonly="True"/>
<field name="gateway_id"/>
<field name="company_id" groups="base.group_multi_company"/>
<separator string="SMS Message" colspan="4"/>
<field name="message" colspan="4" nolabel="1"/>
<separator string="Last Error" colspan="4"/>
<field name="error" colspan="4" nolabel="1"/>
</group>
</sheet>
</form>
</field>
</record>
<record model="ir.actions.act_window" id="action_sms_sms_tree">
<field name="name">Sms</field>
<field name="res_model">sms.sms</field>
<field name="view_type">form</field>
<field name="view_mode">form,tree</field>
<field name="view_id" ref="sms_sms_tree" />
</record>
<menuitem name="SMS Message"
id="menu_gateway_administration_sms"
sequence="110"
parent="base_phone.menu_config_phone"
action="action_sms_sms_tree"/>
<act_window context="{'gateway_id': active_id}"
domain="[('gateway_id', '=', active_id)]"
id="act_sms_gateway_2_sms"
name="Sms Message"
res_model="sms.sms"
src_model="sms.gateway"/>
</odoo>

23
smsclient_core/views/smstemplate_view.xml

@ -1,23 +0,0 @@
<?xml version="1.0"?>
<openerp>
<data>
<!-- ************************************************************** -->
<!-- ** SMS Template ****************************************** -->
<!-- ************************************************************** -->
<record model="ir.ui.view" id="email_template_form">
<field name="name">email.template.form</field>
<field name="model">mail.template</field>
<field name="inherit_id" ref="mail.email_template_form"/>
<field name="arch" type="xml">
<field name="email_to" position="after">
<field name="mobile_to"/>
</field>
<field name="lang" position="before">
<field name="sms_template"/>
<field name="gateway_id"/>
</field>
</field>
</record>
</data>
</openerp>

22
smsclient_core/wizard/__init__.py

@ -1,22 +0,0 @@
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>)
# Copyright (C) 2013 Julius Network Solutions SARL <contact@julius.fr>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>
#
##############################################################################
from . import mass_sms

55
smsclient_core/wizard/mass_sms_view.xml

@ -1,55 +0,0 @@
<?xml version="1.0"?>
<openerp>
<data>
<record model="ir.ui.view" id="view_wizard_send_sms">
<field name="model">wizard.send.sms</field>
<field name="arch" type="xml">
<form string="SMS Gateway - Sens SMS" version="7.0">
<group string="Gateway" colspan="4">
<field name="gateway_id"/>
</group>
<notebook>
<page string="Message">
<field name="message" colspan="4" nolabel="1"/>
<!-- TODO limit to 10 the number of partner to show -->
<field name="partner_ids" colspan="4" nolabel="1">
<tree options="{'limit': 10}">
<field name="name"/>
<field name="mobile"/>
</tree>
</field>
</page>
<page string="Additional option">
<group>
<group>
<field name="validity"/>
<field name="classes"/>
<field name="deferred"/>
<field name="nostop"/>
</group>
<group>
<field name="priority"/>
<field name="coding"/>
<field name="tag"/>
</group>
</group>
</page>
</notebook>
<footer>
<button string="Send SMS" name="send" type="object" class="oe_highlight"/>
or
<button string="Cancel" class="oe_link" special="cancel"/>
</footer>
</form>
</field>
</record>
<act_window name="Send an SMS"
res_model="wizard.send.sms"
src_model="res.partner"
view_mode="form"
target="new"
key2="client_action_multi"
id="action_wizard_send_sms" />
</data>
</openerp>

45
smsclient_ovh/models/keychain.py

@ -1,45 +0,0 @@
# coding: utf-8
# Copyright (C) 2015 Sébastien BEAU <sebastien.beau@akretion.com>
# Valentin CHEMIERE <valentin.chemiere@akretion.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import models, fields
from functools import wraps
def implemented_by_provider(func):
"""Decorator: call _provider_prefixed method instead.
Usage:
@implemented_by_provider
def _do_something()
def _laposte_do_something()
def _gls_do_something()
At runtime, sms-client._do_something() will try to call
the provider spectific method or fallback to generic _do_something
"""
@wraps(func)
def wrapper(cls, *args, **kwargs):
fun_name = func.__name__
fun = '_%s%s' % (cls.provider_type, fun_name)
if not hasattr(cls, fun):
fun = '_provider%s' % (fun_name)
# return func(cls, *args, **kwargs)
return getattr(cls, fun)(*args, **kwargs)
return wrapper
OVH_KEYCHAIN_NAMESPACE = 'ovh_provider'
class AccountProduct(models.Model):
_inherit = 'keychain.account'
namespace = fields.Selection(
selection_add=[(OVH_KEYCHAIN_NAMESPACE, 'Ovh_sms')])
def _ovh_provider_init_data(self):
return {'sms_account': ""}
def _ovh_provider_validate_data(self, data):
return True
Loading…
Cancel
Save