Browse Source

Merge remote-tracking branch 'upstream/8.0' into 9.0-merge-b6e8926

pull/120/head
Ildar Nasyrov 7 years ago
parent
commit
c8d3c22509
No known key found for this signature in database GPG Key ID: D1FDACDF9B83578
  1. 13
      im_notif/README.rst
  2. 9
      im_notif/__init__.py
  3. 19
      im_notif/__openerp__.py
  4. 4
      im_notif/doc/changelog.rst
  5. 19
      im_notif/im_notif_data.xml
  6. 160
      im_notif/im_notif_models.py
  7. 12
      im_notif/im_notif_views.xml
  8. BIN
      im_notif/images/my-pref.png
  9. BIN
      im_notif/static/description/icon.png
  10. BIN
      im_notif/static/description/im-chat.png
  11. 69
      im_notif/static/description/index.html
  12. BIN
      im_notif/static/description/my-pref-button.png
  13. 44
      im_notif/static/src/js/im_notif.js
  14. 67
      mail_sent/i18n/pt.po
  15. 67
      mail_sent/i18n/pt_BR.po

13
im_notif/README.rst

@ -0,0 +1,13 @@
IM Notifications
================
Description: https://apps.odoo.com/apps/modules/8.0/im_notif/
Further information and discussion: https://yelizariev.github.io/odoo/module/2015/02/18/im-notifications.html
Tested on Odoo 8.0 ab7b5d7732a7c222a0aea45bd173742acd47242d
Odoo 9.0+
=========
For newer version the module is not needed, cause there is similar built-in feature

9
im_notif/__init__.py

@ -0,0 +1,9 @@
# -*- coding: utf-8 -*-
from . import im_notif_models
def pre_uninstall(cr, registry):
query = ("UPDATE res_partner "
"SET notify_email = 'always' "
"WHERE notify_email LIKE 'im%';")
cr.execute(query)

19
im_notif/__openerp__.py

@ -0,0 +1,19 @@
# -*- coding: utf-8 -*-
{
'name': 'IM Notifications',
'version': '1.0.1',
'author': 'IT-Projects LLC, Ivan Yelizariev',
'license': 'GPL-3',
'category': 'Tools',
'website': 'https://twitter.com/yelizariev',
'price': 9.00,
'currency': 'EUR',
'depends': ['im_chat', 'mail'],
'images': ['images/my-pref.png'],
'data': [
'im_notif_data.xml',
'im_notif_views.xml',
],
'installable': True,
'uninstall_hook': 'pre_uninstall',
}

4
im_notif/doc/changelog.rst

@ -0,0 +1,4 @@
`1.0.1`
-------
- Hide Notifications user

19
im_notif/im_notif_data.xml

@ -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>

160
im_notif/im_notif_models.py

@ -0,0 +1,160 @@
# -*- coding: utf-8 -*-
from openerp import SUPERUSER_ID
from openerp import models
from openerp import tools
from openerp.osv import fields as old_fields
class ResPartner(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"
),
}
class MailNotification(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 not len(partner.user_ids):
# send notification to partner, that doesn't have odoo account, but has "im*" value in notify_email
send_email = True
if send_email:
email_pids.append(partner.id)
return email_pids, im_uids
def _message2im(self, cr, uid, message):
inbox_action = self.pool['ir.model.data'].xmlid_to_res_id(cr, SUPERUSER_ID, 'mail.mail_inboxfeeds')
inbox_url = '#menu_id=%s' % inbox_action
url = None
if message.res_id:
url = '#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
about = message.subject or message.record_name or 'UNDEFINED'
about = '[ABOUT] %s' % about
if url:
about = '<a href="%s">%s</a>' % (url, about)
im_text = [
'_____________________',
'<a href="%s">_____[open_inbox]_____</a>' % inbox_url,
'%s [FROM] %s' % (message.type, author),
about,
]
# 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)
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(cr, uid, 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)
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

12
im_notif/im_notif_views.xml

@ -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>

BIN
im_notif/images/my-pref.png

After

Width: 748  |  Height: 400  |  Size: 37 KiB

BIN
im_notif/static/description/icon.png

After

Width: 100  |  Height: 100  |  Size: 3.0 KiB

BIN
im_notif/static/description/im-chat.png

After

Width: 240  |  Height: 342  |  Size: 28 KiB

69
im_notif/static/description/index.html

@ -0,0 +1,69 @@
<section class="oe_container">
<div class="oe_row oe_spaced">
<div class="oe_span12">
<h2 class="oe_slogan">IM Notifications</h2>
<h3 class="oe_slogan">Get instant notification inside odoo</h3>
</div>
<div class="oe_span6">
<p class="oe_mt32">
A user is able to select option for notifications:
<ul class="org-ul">
<li>Never </li>
<li>Only IM (if online) </li>
<li>IM (if online) + email (if offline) </li>
<li>IM (if online) + email </li>
<li>Only Emails </li></ul>
</p>
</div>
<div class="oe_span6">
<div class="oe_picture">
<img src="my-pref-button.png"/>
</div>
</div>
</div>
</section>
<section class="oe_container oe_dark">
<div class="oe_row oe_spaced">
<div class="oe_span6">
<p class="oe_mt32">
Each notification includes:
<ul>
<li>Message type: email, comment or notification </li>
<li>Author's name </li>
<li>Subject with a link to related record (if exists) </li>
<li>Link to inbox </li>
</ul>
</p>
</div>
<div class="oe_span6">
<div class="oe_picture">
<img src="im-chat.png?3"/>
</div>
</div>
<div class="oe_span12">
<p class="oe_mt32">
Further information and discussion: <a href="https://yelizariev.github.io/odoo/module/2015/02/18/im-notifications.html">https://yelizariev.github.io/odoo/module/2015/02/18/im-notifications.html</a>
</p>
</div>
</div>
</section>
<section class="oe_container">
<div class="oe_row oe_spaced">
<div class="oe_span12">
<h2>Need our service?</h2>
<p class="oe_mt32">Contact us by <a href="mailto:it@it-projects.info">email</a> or fill out <a href="https://www.it-projects.info/page/website.contactus " target="_blank">request form</a></p>
<ul>
<li><a href="mailto:it@it-projects.info">it@it-projects.info <i class="fa fa-envelope-o"></i></a></li>
<li><a href="https://www.it-projects.info/page/website.contactus " target="_blank">
https://www.it-projects.info/page/website.contactus <i class="fa fa-list-alt"></i></a></li>
</ul>
</div>
</div>
</section>

BIN
im_notif/static/description/my-pref-button.png

After

Width: 260  |  Height: 220  |  Size: 16 KiB

44
im_notif/static/src/js/im_notif.js

@ -0,0 +1,44 @@
(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#!:.?+=&%@!\-\/]))?|(<a)[^>]*href="([^"]*)"[^>]*>([^<]*)<\/a>)/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 href = '';
var content = '';
var is_odoo_ref = false;
if (result[8]=='<a'){
href = result[9];
if (href[0]=='#'){
href += '&rnd='+parseInt(Math.random()*1000);
content = result[10];
is_odoo_ref = true;
} else {
//only internal urls are allowed
href = '';
}
}else{
href = _.escape(result[0]);
content = href;
}
txt += '<a href="' + href + '"' + (is_odoo_ref?'':' target="_blank"')+'>' + content + '</a>';
}
txt += _.escape(str.slice(last, str.length));
return txt;
},
});
})();

67
mail_sent/i18n/pt.po

@ -0,0 +1,67 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * mail_sent
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 8.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-03-29 18:57+0000\n"
"PO-Revision-Date: 2017-03-29 18:57+0000\n"
"Last-Translator: <>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
#. module: mail_sent
#: model:ir.actions.client,help:mail_sent.action_mail_sent_feeds
msgid "<p>\n"
" No message found and no message sent yet.\n"
" </p><p>\n"
" Click on the top-right icon to compose a message. This\n"
" message will be sent by email if it's an internal contact.\n"
" </p>\n"
" "
msgstr "<p>\n"
" Nenhuma mensagem encontrada e nenhuma enviada ainda.\n"
" </p><p>\n"
" Clique no ícone no canto superior direito para compor uma nova mensagem.\n"
" Esta mensagem será enviada por e-mail se não for um contato interno.\n"
" </p>\n"
" "
#. module: mail_sent
#: model:ir.model,name:mail_sent.model_mail_compose_message
msgid "Email composition wizard"
msgstr "Assistente de composição de Email"
#. module: mail_sent
#: model:ir.model,name:mail_sent.model_mail_message
msgid "Message"
msgstr "Mensagem"
#. module: mail_sent
#: model:ir.model,name:mail_sent.model_mail_notification
msgid "Notifications"
msgstr "Notificações"
#. module: mail_sent
#: model:ir.actions.client,name:mail_sent.action_mail_sent_feeds
#: model:ir.ui.menu,name:mail_sent.mail_sentfeeds
#: field:mail.compose.message,sent:0
#: field:mail.message,sent:0
msgid "Sent"
msgstr "Enviados"
#. module: mail_sent
#: help:mail.message,sent:0
msgid "Was message sent to someone"
msgstr "Foi enviada mensagem para alguém"
#. module: mail_sent
#: help:mail.compose.message,sent:0
msgid "dummy field to fix inherit error"
msgstr "campo fictício para corrigir o erro da herança"

67
mail_sent/i18n/pt_BR.po

@ -0,0 +1,67 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * mail_sent
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 8.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-03-29 18:57+0000\n"
"PO-Revision-Date: 2017-03-29 18:57+0000\n"
"Last-Translator: <>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
#. module: mail_sent
#: model:ir.actions.client,help:mail_sent.action_mail_sent_feeds
msgid "<p>\n"
" No message found and no message sent yet.\n"
" </p><p>\n"
" Click on the top-right icon to compose a message. This\n"
" message will be sent by email if it's an internal contact.\n"
" </p>\n"
" "
msgstr "<p>\n"
" Nenhuma mensagem encontrada e nenhuma enviada ainda.\n"
" </p><p>\n"
" Clique no ícone no canto superior direito para compor uma nova mensagem.\n"
" Esta mensagem será enviada por e-mail se não for um contato interno.\n"
" </p>\n"
" "
#. module: mail_sent
#: model:ir.model,name:mail_sent.model_mail_compose_message
msgid "Email composition wizard"
msgstr "Assistente de Composição de Email"
#. module: mail_sent
#: model:ir.model,name:mail_sent.model_mail_message
msgid "Message"
msgstr "Mensagem"
#. module: mail_sent
#: model:ir.model,name:mail_sent.model_mail_notification
msgid "Notifications"
msgstr "Notificações"
#. module: mail_sent
#: model:ir.actions.client,name:mail_sent.action_mail_sent_feeds
#: model:ir.ui.menu,name:mail_sent.mail_sentfeeds
#: field:mail.compose.message,sent:0
#: field:mail.message,sent:0
msgid "Sent"
msgstr "Enviados"
#. module: mail_sent
#: help:mail.message,sent:0
msgid "Was message sent to someone"
msgstr "Foi enviada mensagem para alguém"
#. module: mail_sent
#: help:mail.compose.message,sent:0
msgid "dummy field to fix inherit error"
msgstr "campo fictício para corrigir o erro da herança"
Loading…
Cancel
Save