From e7211e4145cce8cac6ff23d1facd885b157d2aa7 Mon Sep 17 00:00:00 2001 From: Ivan Yelizariev Date: Fri, 16 Jan 2015 12:03:40 +0200 Subject: [PATCH] upload im_notif --- im_notif/__init__.py | 1 + im_notif/__openerp__.py | 26 +++++ im_notif/im_notif_data.xml | 19 ++++ im_notif/im_notif_models.py | 154 +++++++++++++++++++++++++++++ im_notif/im_notif_views.xml | 12 +++ im_notif/static/src/js/im_notif.js | 31 ++++++ 6 files changed, 243 insertions(+) create mode 100644 im_notif/__init__.py create mode 100644 im_notif/__openerp__.py create mode 100644 im_notif/im_notif_data.xml create mode 100644 im_notif/im_notif_models.py create mode 100644 im_notif/im_notif_views.xml create mode 100644 im_notif/static/src/js/im_notif.js diff --git a/im_notif/__init__.py b/im_notif/__init__.py new file mode 100644 index 0000000..6ff86bc --- /dev/null +++ b/im_notif/__init__.py @@ -0,0 +1 @@ +import im_notif_models diff --git a/im_notif/__openerp__.py b/im_notif/__openerp__.py new file mode 100644 index 0000000..90e3302 --- /dev/null +++ b/im_notif/__openerp__.py @@ -0,0 +1,26 @@ +{ + 'name' : 'IM Notifications', + 'version' : '1.0.0', + 'author' : 'Ivan Yelizariev', + 'category' : 'Sale', + 'website' : 'https://it-projects.info', + 'description': """ +Allows to sent nofitications via IM. + +Options for notifications: + +* Never +* Only IM (if online) +* IM (if online) + email (if offline) +* IM (if online) + email +* Only Emails + +Tested on Odoo 8.0 ab7b5d7732a7c222a0aea45bd173742acd47242d + """, + 'depends' : ['im_chat', 'mail'], + 'data':[ + 'im_notif_data.xml', + 'im_notif_views.xml', + ], + 'installable': True +} diff --git a/im_notif/im_notif_data.xml b/im_notif/im_notif_data.xml new file mode 100644 index 0000000..0d2f6b8 --- /dev/null +++ b/im_notif/im_notif_data.xml @@ -0,0 +1,19 @@ + + + + + Notifications + + Technical profile. You should not delete it. + + + Notifications + notifications + + + + + + + + diff --git a/im_notif/im_notif_models.py b/im_notif/im_notif_models.py new file mode 100644 index 0000000..85ff60d --- /dev/null +++ b/im_notif/im_notif_models.py @@ -0,0 +1,154 @@ +import openerp +from openerp import api, models, fields, SUPERUSER_ID, tools +from openerp.osv import fields as old_fields +from openerp.tools import html2plaintext +from openerp.tools.translate import _ + +class res_partner(models.Model): + _inherit = 'res.partner' + _columns = { + 'notify_email': old_fields.selection([ + ('none', 'Never'), + ('im', 'Only IM (if online)'), + ('im_xor_email', 'IM (if online) + email (if offline)'), + ('im_and_email', 'IM (if online) + email'), + ('always', 'Only emails'), + ], 'Receive Inbox Notifications by Email, IM', required=True, + oldname='notification_email_send', + help="Policy to receive emails, IM for new messages pushed to your personal Inbox. IM can be used only for partners with odoo user account" + ), + } + + _defaults = { + 'notify_email': lambda *args: 'always' + } + +class mail_notification(models.Model): + _inherit = 'mail.notification' + + def get_recipients(self, cr, uid, ids, message, context=None): + # based on addons/mail/mail_followers.py::get_partners_to_email + """ Return the list of partners to notify, based on their preferences. + + :param browse_record message: mail.message to notify + :param list partners_to_notify: optional list of partner ids restricting + the notifications to process + """ + email_pids = [] + im_uids = [] + for notification in self.browse(cr, uid, ids, context=context): + if notification.is_read: + continue + partner = notification.partner_id + # Do not send to partners without email address defined + if not partner.email: + continue + # Do not send to partners having same email address than the author (can cause loops or bounce effect due to messy database) + if message.author_id and message.author_id.email == partner.email: + continue + # Partner does not want to receive any emails or is opt-out + n = partner.notify_email + if n == 'none': + continue + if n == 'always': + email_pids.append(partner.id) + continue + send_email = False + for user in partner.user_ids: + if user.im_status=='offline': + if n != 'im': + send_email = True + else: + im_uids.append(user.id) + if n == 'im_and_email': + send_email = True + if send_email: + email_pids.append(partner.id) + + return email_pids, im_uids + + def _message2im(self, message): + url = 'ODOO_REF#id=%s&model=%s&view_type=form' % ( + message.res_id, + message.model + ) + author = message.author_id and message.author_id.name_get() + author = author and author[0][1] or message.email_from + body = html2plaintext(message.body)[:100] or '' + mtype = {'email': _('Email'), + 'comment': _('Comment'), + 'notification': _('System notification'), + }.get(message.type, '') + + im_text = ['NEW %s FROM %s' % (message.type, author), + 'OPEN %s: %s' % (message.record_name or '', url) + ] + im_text = im_text + body.split('\n') + return im_text + + + def _notify_email(self, cr, uid, ids, message_id, force_send=False, user_signature=True, context=None): + # based on addons/mail/mail_followers.py::_notify_email + message = self.pool['mail.message'].browse(cr, SUPERUSER_ID, message_id, context=context) + + # compute partners + email_pids, im_uids = self.get_recipients(cr, uid, ids, message, context=None) + print 'recipients', email_pids, im_uids + if email_pids: + self._do_notify_email(cr, uid, email_pids, message, force_send, user_signature, context) + + if im_uids: + self._do_notify_im(cr, uid, im_uids, message, context) + + return True + + def _do_notify_im(self, cr, uid, im_uids, message, context=None): + im_text = self._message2im(message) + + user_from = self.pool['ir.model.data'].xmlid_to_res_id(cr, SUPERUSER_ID, 'im_notif.notif_user') + + session_obj = self.pool['im_chat.session'] + message_type = 'message' + for user_to in im_uids: + session = session_obj.session_get(cr, user_from, user_to, context=context) + uuid = session.get('uuid') + message_content = '\n'.join(im_text) + message_id = self.pool["im_chat.message"].post(cr, SUPERUSER_ID, user_from, uuid, message_type, message_content, context=context) + + return True + + + def _do_notify_email(self, cr, uid, email_pids, message, force_send=False, user_signature=True, context=None): + + # compute email body (signature, company data) + body_html = message.body + # add user signature except for mail groups, where users are usually adding their own signatures already + user_id = message.author_id and message.author_id.user_ids and message.author_id.user_ids[0] and message.author_id.user_ids[0].id or None + signature_company = self.get_signature_footer(cr, uid, user_id, res_model=message.model, res_id=message.res_id, context=context, user_signature=(user_signature and message.model != 'mail.group')) + if signature_company: + body_html = tools.append_content_to_html(body_html, signature_company, plaintext=False, container_tag='div') + # compute email references + references = message.parent_id.message_id if message.parent_id else False + + # custom values + custom_values = dict() + if message.model and message.res_id and self.pool.get(message.model) and hasattr(self.pool[message.model], 'message_get_email_values'): + custom_values = self.pool[message.model].message_get_email_values(cr, uid, message.res_id, message, context=context) + + # create email values + max_recipients = 50 + chunks = [email_pids[x:x + max_recipients] for x in xrange(0, len(email_pids), max_recipients)] + email_ids = [] + for chunk in chunks: + mail_values = { + 'mail_message_id': message.id, + 'auto_delete': True, + 'body_html': body_html, + 'recipient_ids': [(4, id) for id in chunk], + 'references': references, + } + mail_values.update(custom_values) + email_ids.append(self.pool.get('mail.mail').create(cr, uid, mail_values, context=context)) + if force_send and len(chunks) < 2: # for more than 50 followers, use the queue system + self.pool.get('mail.mail').send(cr, uid, email_ids, context=context) + return True diff --git a/im_notif/im_notif_views.xml b/im_notif/im_notif_views.xml new file mode 100644 index 0000000..ac90b0a --- /dev/null +++ b/im_notif/im_notif_views.xml @@ -0,0 +1,12 @@ + + + + + + + diff --git a/im_notif/static/src/js/im_notif.js b/im_notif/static/src/js/im_notif.js new file mode 100644 index 0000000..523656e --- /dev/null +++ b/im_notif/static/src/js/im_notif.js @@ -0,0 +1,31 @@ + (function(){ + + "use strict"; + + var _t = openerp._t; + var _lt = openerp._lt; + var QWeb = openerp.qweb; + + openerp.im_chat.Conversation.include({ + escape_keep_url: function(str){ + //var url_regex = /(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/gi; + var url_regex = /((ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?|ODOO_REF#[\w#!:.?+=&%@!\-\/]+)/gi; + var last = 0; + var txt = ""; + while (true) { + var result = url_regex.exec(str); + if (! result) + break; + txt += _.escape(str.slice(last, result.index)); + last = url_regex.lastIndex; + var is_odoo_ref = result[0].match(/^ODOO_REF/) + var url = _.escape(result[0].replace(/^ODOO_REF/, '')); + if (is_odoo_ref) + url += '&rnd='+parseInt(Math.random()*1000); + txt += '' + url + ''; + } + txt += _.escape(str.slice(last, str.length)); + return txt; + }, + }) + })() \ No newline at end of file