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