You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

277 lines
9.7 KiB

7 years ago
  1. # coding: utf-8
  2. # Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>).
  3. # Copyright (C) 2011 SYLEAM (<http://syleam.fr/>)
  4. # Copyright (C) 2013 Julius Network Solutions SARL <contact@julius.fr>
  5. # Copyright (C) 2015 Valentin Chemiere <valentin.chemiere@akretion.com>
  6. # Copyright (C) 2015 Sébastien BEAU <sebastien.beau@akretion.com>
  7. # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
  8. import logging
  9. from odoo import models, fields, api, _
  10. from functools import wraps
  11. _logger = logging.getLogger(__name__)
  12. PRIORITY_LIST = [
  13. ('0', '0'),
  14. ('1', '1'),
  15. ('2', '2'),
  16. ('3', '3')
  17. ]
  18. CLASSES_LIST = [
  19. ('0', 'Flash'),
  20. ('1', 'Phone display'),
  21. ('2', 'SIM'),
  22. ('3', 'Toolkit')
  23. ]
  24. class SMSClient(models.Model):
  25. _name = 'sms.gateway'
  26. _description = 'SMS Client'
  27. @api.model
  28. def get_method(self):
  29. return []
  30. @api.multi
  31. def _provider_get_provider_conf(self):
  32. for rec in self:
  33. keychain = rec.env['keychain.account']
  34. if rec._check_permissions:
  35. retrieve = keychain.suspend_security().retrieve
  36. else:
  37. retrieve = keychain.retrieve
  38. accounts = retrieve(
  39. [['namespace', '=', 'SMS_Gateway%s' % rec.provider_type]])
  40. return accounts[0]
  41. # @api.multi
  42. # def _get_provider_conf(self):
  43. # for sms_provider in self:
  44. # global_section_name = 'sms_provider'
  45. # config_vals = {}
  46. # if serv_config.has_section(global_section_name):
  47. # config_vals.update(serv_config.items(global_section_name))
  48. # custom_section_name = '.'.join((global_section_name,
  49. # sms_provider.name))
  50. # if serv_config.has_section(custom_section_name):
  51. # config_vals.update(serv_config.items(custom_section_name))
  52. # for key in config_vals:
  53. # sms_provider[key] = config_vals[key]
  54. name = fields.Char(string='Gateway Name', required=True)
  55. url = fields.Char(
  56. string='Gateway URL', compute='_get_provider_conf',
  57. help='Base url for message')
  58. url_visible = fields.Boolean(default=False)
  59. method = fields.Selection(
  60. string='API Method',
  61. selection='get_method')
  62. state = fields.Selection(selection=[
  63. ('new', 'Not Verified'),
  64. ('waiting', 'Waiting for Verification'),
  65. ('confirm', 'Verified'),
  66. ], string='Gateway Status', index=True, readonly=True, default='new')
  67. user_ids = fields.Many2many(
  68. comodel_name='res.users',
  69. string='Users Allowed')
  70. sms_account = fields.Char(compute='_get_provider_conf')
  71. sms_account_visible = fields.Boolean(default=False)
  72. login_provider = fields.Char(compute='_get_provider_conf')
  73. login_provider_visible = fields.Boolean(default=False)
  74. password_provider = fields.Char(compute='_get_provider_conf')
  75. password_provider_visible = fields.Boolean(default=False)
  76. from_provider = fields.Char(compute='_get_provider_conf')
  77. from_provider_visible = fields.Boolean(default=False)
  78. code = fields.Char('Verification Code')
  79. code_visible = fields.Boolean(default=False)
  80. body = fields.Text(
  81. string='Message',
  82. help="The message text that will be send along with the"
  83. " email which is send through this server.")
  84. validity = fields.Integer(
  85. default=10,
  86. help="The maximum time - in minute(s) - before the message "
  87. "is dropped.")
  88. validity_visible = fields.Boolean(default=False)
  89. classes = fields.Selection(
  90. selection=CLASSES_LIST, string='Class',
  91. default='1',
  92. help='The SMS class: flash(0),phone display(1),SIM(2),toolkit(3)')
  93. classes_visible = fields.Boolean(default=False)
  94. deferred = fields.Integer(
  95. default=0,
  96. help='The time -in minute(s)- to wait before sending the message.')
  97. deferred_visible = fields.Boolean(default=False)
  98. priority = fields.Selection(
  99. selection=PRIORITY_LIST, string='Priority', default='3',
  100. help='The priority of the message')
  101. priority_visible = fields.Boolean(default=False)
  102. coding = fields.Selection(selection=[
  103. ('1', '7 bit'),
  104. ('2', 'Unicode')
  105. ], string='Coding',
  106. help='The SMS coding: 1 for 7 bit (160 chracters max'
  107. 'lenght) or 2 for unicode (70 characters max'
  108. 'lenght)',
  109. default='1'
  110. )
  111. coding_visible = fields.Boolean(default=False)
  112. tag = fields.Char('Tag', help='an optional tag')
  113. tag_visible = fields.Boolean(default=False)
  114. nostop = fields.Boolean(
  115. default=True,
  116. help='Do not display STOP clause in the message, this requires that '
  117. 'this is not an advertising message.')
  118. nostop_visible = fields.Boolean(default=False)
  119. char_limit = fields.Boolean('Character Limit', default=True)
  120. char_limit_visible = fields.Boolean(default=False)
  121. default_gateway = fields.Boolean(default=False)
  122. company_id = fields.Many2one(comodel_name='res.company')
  123. @api.onchange('method')
  124. def onchange_method(self):
  125. if not self.method:
  126. self.url_visible = False
  127. self.sms_account_visible = False
  128. self.login_provider_visible = False
  129. self.password_provider_visible = False
  130. self.from_provider_visible = False
  131. self.validity_visible = False
  132. self.classes_visible = False
  133. self.deferred_visible = False
  134. self.nostop_visible = False
  135. self.priority_visible = False
  136. self.coding_visible = False
  137. self.tag_visible = False
  138. self.char_limit_visible = False
  139. @api.multi
  140. def _check_permissions(self):
  141. self.ensure_one()
  142. if self.env.uid not in self.sudo().user_ids.ids:
  143. return False
  144. return True
  145. @api.model
  146. def _run_send_sms(self, domain=None):
  147. if domain is None:
  148. domain = []
  149. domain.append(('state', '=', 'draft'))
  150. sms = self.env['sms.sms'].search(domain)
  151. return sms.send()
  152. class SmsSms(models.Model):
  153. _name = 'sms.sms'
  154. _description = 'SMS'
  155. _rec_name = 'mobile'
  156. message = fields.Text(
  157. size=256,
  158. required=True,
  159. readonly=True,
  160. states={'draft': [('readonly', False)]})
  161. mobile = fields.Char(
  162. required=True,
  163. readonly=True,
  164. states={'draft': [('readonly', False)]})
  165. gateway_id = fields.Many2one(
  166. comodel_name='sms.gateway',
  167. string='SMS Gateway',
  168. readonly=True,
  169. states={'draft': [('readonly', False)]})
  170. state = fields.Selection(selection=[
  171. ('draft', 'Queued'),
  172. ('sent', 'Sent'),
  173. ('cancel', 'Cancel'),
  174. ('error', 'Error'),
  175. ], string='Message Status',
  176. select=True,
  177. readonly=True,
  178. default='draft')
  179. error = fields.Text(
  180. string='Last Error',
  181. size=256,
  182. readonly=True,
  183. states={'draft': [('readonly', False)]})
  184. validity = fields.Integer(
  185. string='Validity',
  186. readonly=True,
  187. states={'draft': [('readonly', False)]},
  188. help='The maximum time -in minute(s)- before the message is dropped.')
  189. classes = fields.Selection(
  190. selection=CLASSES_LIST,
  191. readonly=True,
  192. states={'draft': [('readonly', False)]},
  193. help='The sms class: flash(0), phone display(1), SIM(2), toolkit(3)')
  194. deferred = fields.Integer(
  195. readonly=True,
  196. states={'draft': [('readonly', False)]},
  197. help='The time -in minute(s)- to wait before sending the message.')
  198. priority = fields.Selection(
  199. readonly=True,
  200. states={'draft': [('readonly', False)]},
  201. selection=PRIORITY_LIST,
  202. help='The priority of the message ')
  203. coding = fields.Selection([
  204. ('1', '7 bit'),
  205. ('2', 'Unicode')
  206. ], readonly=True,
  207. states={'draft': [('readonly', False)]},
  208. help='The sms coding: 1 for 7 bit or 2 for unicode')
  209. tag = fields.Char(
  210. size=256,
  211. readonly=True,
  212. states={'draft': [('readonly', False)]},
  213. help='An optional tag')
  214. nostop = fields.Boolean(
  215. string='NoStop',
  216. readonly=True,
  217. states={'draft': [('readonly', False)]},
  218. help='Do not display STOP clause in the message, this requires that'
  219. 'this is not an advertising message.')
  220. partner_id = fields.Many2one(
  221. 'res.partner',
  222. readonly=True,
  223. states={'draft': [('readonly', False)]},
  224. string='Partner')
  225. company_id = fields.Many2one(
  226. comodel_name='res.company',
  227. readonly=True,
  228. states={'draft': [('readonly', False)]})
  229. @api.onchange('partner_id')
  230. def onchange_partner_id(self):
  231. self.mobile = self.partner_id.mobile
  232. @api.multi
  233. def send(self):
  234. for sms in self:
  235. if sms.gateway_id.char_limit and len(sms.message) > 160:
  236. sms.write({
  237. 'state': 'error',
  238. 'error': _('Size of SMS should not be more then 160 char'),
  239. })
  240. if not hasattr(sms, "_send_%s" % sms.gateway_id.method):
  241. raise NotImplemented
  242. else:
  243. try:
  244. with sms._cr.savepoint():
  245. getattr(sms, "_send_%s" % sms.gateway_id.method)()
  246. sms.write({'state': 'sent', 'error': ''})
  247. except Exception, e:
  248. _logger.error('Failed to send sms %s', e)
  249. sms.write({'error': e, 'state': 'error'})
  250. sms._cr.commit()
  251. return True
  252. @api.multi
  253. def cancel(self):
  254. self.write({'state': 'cancel'})
  255. @api.multi
  256. def retry(self):
  257. self.write({'state': 'draft'})