Ivan Yelizariev
10 years ago
committed by
Ivan Yelizariev
6 changed files with 243 additions and 0 deletions
-
1im_notif/__init__.py
-
26im_notif/__openerp__.py
-
19im_notif/im_notif_data.xml
-
154im_notif/im_notif_models.py
-
12im_notif/im_notif_views.xml
-
31im_notif/static/src/js/im_notif.js
@ -0,0 +1 @@ |
|||
import im_notif_models |
@ -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 |
|||
} |
@ -0,0 +1,19 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<openerp> |
|||
<data> |
|||
<record id="notif_partner" model="res.partner"> |
|||
<field name="name">Notifications</field> |
|||
<field name="active" eval="False"/> |
|||
<field name="comment">Technical profile. You should not delete it.</field> |
|||
</record> |
|||
<record id="notif_user" model="res.users"> |
|||
<field name="name">Notifications</field> |
|||
<field name="login">notifications</field> |
|||
<field name="password"></field> |
|||
<field name="groups_id" eval="[(6,0,[ref('base.group_user')])]"/> |
|||
<!--<field name="image" type="base64" file="base/static/img/public_user-image.png"/>--> |
|||
<field name="partner_id" ref="notif_partner"/> |
|||
<field name="active" eval="True"/> |
|||
</record> |
|||
</data> |
|||
</openerp> |
@ -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 |
@ -0,0 +1,12 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<openerp> |
|||
<data> |
|||
<template id="assets_backend" name="im_notif assets" inherit_id="web.assets_backend"> |
|||
<xpath expr="." position="inside"> |
|||
<!--<link rel="stylesheet" href="/im_notif/static/src/css/im_notif.css"/>--> |
|||
<script type="text/javascript" src="/im_notif/static/src/js/im_notif.js"></script> |
|||
</xpath> |
|||
</template> |
|||
|
|||
</data> |
|||
</openerp> |
@ -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 += '<a href="' + url + '"' + (is_odoo_ref?'':' target="_blank"')+'>' + url + '</a>'; |
|||
} |
|||
txt += _.escape(str.slice(last, str.length)); |
|||
return txt; |
|||
}, |
|||
}) |
|||
})() |
Write
Preview
Loading…
Cancel
Save
Reference in new issue