Merge pull request #1 from KolushovAlexandr/11.0-merge_commit_conflict_resolving
11.0 merge commit conflict resolvingpull/170/head
-
7.travis.yml
-
3README.md
-
35mail_all/README.rst
-
3mail_all/__init__.py
-
11mail_all/__manifest__.py
-
3mail_all/doc/changelog.rst
-
10mail_all/doc/index.rst
-
8mail_all/i18n/es.po
-
1mail_all/models/__init__.py
-
2mail_all/static/description/index.html
-
3mail_all/static/src/css/mail_all.css
-
54mail_all/static/src/js/mail_all.js
-
2mail_all/static/src/xml/menu.xml
-
1mail_all/tests/__init__.py
-
1mail_all/tests/test_js.py
-
1mail_all/views/templates.xml
-
40mail_archives/README.rst
-
1mail_archives/__init__.py
-
3mail_archives/__manifest__.py
-
0mail_archives/doc/changelog.rst
-
20mail_archives/doc/index.rst
-
10mail_archives/i18n/es.po
-
6mail_archives/static/description/index.html
-
3mail_archives/static/src/css/archives.css
-
63mail_archives/static/src/js/archives.js
-
2mail_archives/static/src/xml/menu.xml
-
1mail_archives/tests/__init__.py
-
1mail_archives/tests/test_js.py
-
1mail_archives/views/templates.xml
-
35mail_attachment_popup/README.rst
-
0mail_attachment_popup/__init__.py
-
16mail_attachment_popup/doc/index.rst
-
26mail_attachment_popup/i18n/ru.po
-
BINmail_attachment_popup/images/popup_image.png
-
BINmail_attachment_popup/static/description/attach_image.png
-
BINmail_attachment_popup/static/description/download.png
-
84mail_attachment_popup/static/description/index.html
-
BINmail_attachment_popup/static/description/popup.png
-
429mail_attachment_popup/static/lib/js/jquery.arcticmodal.js
-
8mail_attachment_popup/static/src/css/jquery.arcticmodal.css
-
11mail_attachment_popup/static/src/css/simple.css
-
16mail_attachment_popup/static/src/css/styles.css
-
BINmail_attachment_popup/static/src/img/loading.gif
-
29mail_attachment_popup/static/src/xml/mail_attachment_popup.xml
-
13mail_attachment_popup/views/mail_attachment_popup_template.xml
-
32mail_base/README.rst
-
1mail_base/__init__.py
-
3mail_base/__manifest__.py
-
1mail_base/controllers/main.py
-
20mail_base/doc/index.rst
-
8mail_base/i18n/es.po
-
10mail_base/i18n/pt.po
-
10mail_base/i18n/pt_BR.po
-
1mail_base/models.py
-
1294mail_base/static/lib/base.js
-
2mail_base/tests/__init__.py
-
16mail_base/tests/test_default.py
-
1mail_check_immediately/__init__.py
-
1mail_check_immediately/__manifest__.py
-
1mail_check_immediately/models.py
-
2mail_check_immediately/static/description/index.html
-
1mail_fix_553/__init__.py
-
1mail_fix_553/__manifest__.py
-
1mail_fix_553/mail_fix_553.py
-
49mail_move_message/README.rst
-
3mail_move_message/__init__.py
-
3mail_move_message/controllers/__init__.py
-
58mail_move_message/controllers/main.py
-
10mail_move_message/data/mail_move_message_data.xml
-
5mail_move_message/doc/changelog.rst
-
35mail_move_message/doc/index.rst
-
195mail_move_message/mail_move_message_models.py
-
79mail_move_message/mail_move_message_views.xml
-
BINmail_move_message/static/description/delete-message.png
-
BINmail_move_message/static/description/icon.png
-
BINmail_move_message/static/description/inbox-move.png
-
74mail_move_message/static/description/index.html
-
BINmail_move_message/static/description/record-move-back.png
-
132mail_move_message/static/src/js/mail_move_message.js
-
8mail_move_message/static/src/xml/mail_move_message_main.xml
-
3mail_move_message/tests/__init__.py
-
52mail_move_message/tests/test_mail_move.py
-
62mail_multi_website/README.rst
-
40mail_multi_website/__init__.py
-
51mail_multi_website/__manifest__.py
-
4mail_multi_website/doc/changelog.rst
-
73mail_multi_website/doc/index.rst
-
BINmail_multi_website/images/main.jpg
-
7mail_multi_website/models/__init__.py
-
20mail_multi_website/models/ir_property.py
-
16mail_multi_website/models/mail_message.py
-
151mail_multi_website/models/mail_template.py
-
26mail_multi_website/models/mail_thread.py
-
45mail_multi_website/models/res_users.py
-
10mail_multi_website/models/website.py
-
0mail_multi_website/static/description/icon.png
-
97mail_multi_website/static/description/index.html
-
4mail_multi_website/tests/__init__.py
-
41mail_multi_website/tests/test_fetch.py
-
10mail_multi_website/tests/test_mail_model.py
@ -1,3 +0,0 @@ |
|||||
# -*- coding: utf-8 -*- |
|
||||
|
|
||||
from . import models |
|
@ -1,6 +1,3 @@ |
|||||
Updates |
|
||||
======= |
|
||||
|
|
||||
`1.0.0` |
`1.0.0` |
||||
------- |
------- |
||||
|
|
||||
|
@ -1 +0,0 @@ |
|||||
# -*- coding: utf-8 -*- |
|
@ -0,0 +1,3 @@ |
|||||
|
.o_channel_name.mail_all i { |
||||
|
margin-right: 4px; |
||||
|
} |
@ -1,3 +1,2 @@ |
|||||
# -*- coding: utf-8 -*- |
|
||||
|
|
||||
from . import test_js |
from . import test_js |
@ -1,15 +1,39 @@ |
|||||
Mail Archives |
|
||||
============= |
|
||||
|
=============== |
||||
|
Mail Archives |
||||
|
=============== |
||||
|
|
||||
Adds Archive menu, which shows sent/received messages |
Adds Archive menu, which shows sent/received messages |
||||
|
|
||||
Usage |
|
||||
----- |
|
||||
Click Discuss/Archive menu -- sent/received messages are displayed |
|
||||
|
Credits |
||||
|
======= |
||||
|
|
||||
|
Contributors |
||||
|
------------ |
||||
|
* Pavel Romanchenko <apps@it-projects.info> |
||||
|
|
||||
|
Sponsors |
||||
|
-------- |
||||
|
* `IT-Projects LLC <https://it-projects.info>`__ |
||||
|
|
||||
|
Maintainers |
||||
|
----------- |
||||
|
* `IT-Projects LLC <https://it-projects.info>`__ |
||||
|
|
||||
|
To get a guaranteed support you are kindly requested to purchase the module at `odoo apps store <https://apps.odoo.com/apps/modules/11.0/mail_archives/>`__. |
||||
|
|
||||
|
Thank you for understanding! |
||||
|
|
||||
|
`IT-Projects Team <https://www.it-projects.info/team>`__ |
||||
|
|
||||
Further information |
Further information |
||||
------------------- |
|
||||
|
=================== |
||||
|
|
||||
|
Demo: http://runbot.it-projects.info/demo/mail_addons/11.0 |
||||
|
|
||||
|
HTML Description: https://apps.odoo.com/apps/modules/11.0/mail_archives/ |
||||
|
|
||||
|
Usage instructions: `<doc/index.rst>`_ |
||||
|
|
||||
HTML Description: https://apps.odoo.com/apps/modules/9.0/mail_archives/ |
|
||||
|
Changelog: `<doc/changelog.rst>`_ |
||||
|
|
||||
Tested on Odoo 9.0 b9f206953e3f877adf18643f154d1262842564ee |
|
||||
|
Tested on Odoo 11.0 ecbf7aa4714479229658d14cce28fa00376ed390 |
@ -1 +0,0 @@ |
|||||
# -*- coding: utf-8 -*- |
|
@ -0,0 +1,20 @@ |
|||||
|
============== |
||||
|
Mail Archives |
||||
|
============== |
||||
|
|
||||
|
Installation |
||||
|
============ |
||||
|
|
||||
|
* `Install <https://odoo-development.readthedocs.io/en/latest/odoo/usage/install-module.html>`__ this module in a usual way |
||||
|
|
||||
|
Configuration |
||||
|
============= |
||||
|
|
||||
|
This module does not require special configuration. |
||||
|
|
||||
|
Usage |
||||
|
===== |
||||
|
|
||||
|
* Open ``Discuss``. |
||||
|
* Click ``Archive``. |
||||
|
* Sent/received messages are displayed. |
@ -0,0 +1,3 @@ |
|||||
|
.o_channel_name.mail_archives i { |
||||
|
margin-right: 4px; |
||||
|
} |
@ -1,3 +1,2 @@ |
|||||
# -*- coding: utf-8 -*- |
|
||||
|
|
||||
from . import test_js |
from . import test_js |
@ -1,35 +0,0 @@ |
|||||
=================== |
|
||||
Popup Attachments |
|
||||
=================== |
|
||||
|
|
||||
The module opens attached mail images in popup. |
|
||||
|
|
||||
Credits |
|
||||
======= |
|
||||
|
|
||||
Contributors |
|
||||
------------ |
|
||||
* Dinar Gabbasov <gabbasov@it-projects.info> |
|
||||
|
|
||||
Sponsors |
|
||||
-------- |
|
||||
* `IT-Projects LLC <https://it-projects.info>`_ |
|
||||
|
|
||||
Maintainers |
|
||||
----------- |
|
||||
* `IT-Projects LLC <https://it-projects.info>`_ |
|
||||
|
|
||||
The module is not maintained in future versions because it's functionality built-in since Odoo 11.0. |
|
||||
|
|
||||
Further information |
|
||||
=================== |
|
||||
|
|
||||
Demo: http://runbot.it-projects.info/demo/mail-addons/9.0 |
|
||||
|
|
||||
HTML Description: https://apps.odoo.com/apps/modules/9.0/mail_attachment_popup/ |
|
||||
|
|
||||
Usage instructions: `<doc/index.rst>`_ |
|
||||
|
|
||||
Changelog: `<doc/changelog.rst>`_ |
|
||||
|
|
||||
Tested on Odoo 9.0 021878f9c41c6d652abf345c3c5537fe92f8bc5b |
|
@ -1,16 +0,0 @@ |
|||||
=================== |
|
||||
Popup Attachments |
|
||||
=================== |
|
||||
|
|
||||
Installation |
|
||||
============ |
|
||||
|
|
||||
* `Install <https://odoo-development.readthedocs.io/en/latest/odoo/usage/install-module.html>`__ this module in a usual way |
|
||||
|
|
||||
Usage |
|
||||
===== |
|
||||
|
|
||||
* Open 'Messaging' menu |
|
||||
* Find any message with image in attachments |
|
||||
* Click on the image |
|
||||
* Browser opens image in popup instead of downloading it |
|
@ -1,26 +0,0 @@ |
|||||
# Translation of Odoo Server. |
|
||||
# This file contains the translation of the following modules: |
|
||||
# * mail_attachment_popup |
|
||||
# |
|
||||
# Translators: |
|
||||
# Dinar <gabbasov@it-projects.info>, 2017 |
|
||||
msgid "" |
|
||||
msgstr "" |
|
||||
"Project-Id-Version: Odoo Server 10.0\n" |
|
||||
"Report-Msgid-Bugs-To: \n" |
|
||||
"POT-Creation-Date: 2017-11-16 08:35+0000\n" |
|
||||
"PO-Revision-Date: 2017-11-16 08:35+0000\n" |
|
||||
"Last-Translator: Dinar <gabbasov@it-projects.info>, 2017\n" |
|
||||
"Language-Team: Russian (https://www.transifex.com/it-projects-llc/teams/76080/ru/)\n" |
|
||||
"MIME-Version: 1.0\n" |
|
||||
"Content-Type: text/plain; charset=UTF-8\n" |
|
||||
"Content-Transfer-Encoding: \n" |
|
||||
"Language: ru\n" |
|
||||
"Plural-Forms: nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n%100>=11 && n%100<=14)? 2 : 3);\n" |
|
||||
|
|
||||
#. module: mail_attachment_popup |
|
||||
#. openerp-web |
|
||||
#: code:addons/mail_attachment_popup/static/src/xml/mail_attachment_popup.xml:17 |
|
||||
#, python-format |
|
||||
msgid "Download" |
|
||||
msgstr "Скачать" |
|
Before Width: 749 | Height: 371 | Size: 128 KiB |
Before Width: 361 | Height: 382 | Size: 63 KiB |
Before Width: 361 | Height: 381 | Size: 131 KiB |
@ -1,84 +0,0 @@ |
|||||
<section class="oe_container"> |
|
||||
<div class="oe_row oe_spaced"> |
|
||||
<div class="oe_span12"> |
|
||||
<h2 class="oe_slogan">Popup Attachments</h2> |
|
||||
<h3 class="oe_slogan">Open attachments in popup</h3> |
|
||||
</div> |
|
||||
</div> |
|
||||
</section> |
|
||||
|
|
||||
<section class="oe_container"> |
|
||||
<div class="oe_row oe_spaced"> |
|
||||
<div class="oe_span12"> |
|
||||
<p class="oe_mt32"> |
|
||||
The module allows to open attachments (images) in popup. It is convenient if you want to display them only without downloading. |
|
||||
</p> |
|
||||
</div> |
|
||||
</div> |
|
||||
</section> |
|
||||
|
|
||||
<section class="oe_container oe_dark"> |
|
||||
<div class="oe_row oe_spaced"> |
|
||||
<div class="oe_span12"> |
|
||||
<h3 class="oe_slogan">How it works</h3> |
|
||||
</div> |
|
||||
</div> |
|
||||
</section> |
|
||||
|
|
||||
<section class="oe_container"> |
|
||||
<div class="oe_row oe_spaced"> |
|
||||
<div class="oe_span6"> |
|
||||
<p class="oe_mt32"> |
|
||||
Go to "Messaging" menu and open email that contains image(s) in attachment. |
|
||||
</p> |
|
||||
</div> |
|
||||
<div class="oe_span6"> |
|
||||
<div class="oe_row_img oe_centered"> |
|
||||
<img class="oe_demo oe_picture oe_screenshot" src="attach_image.png"/> |
|
||||
</div> |
|
||||
</div> |
|
||||
</div> |
|
||||
</section> |
|
||||
|
|
||||
<section class="oe_container oe_dark"> |
|
||||
<div class="oe_row oe_spaced"> |
|
||||
<div class="oe_span6"> |
|
||||
<div class="oe_row_img oe_centered"> |
|
||||
<img class="oe_demo oe_picture oe_screenshot" src="popup.png"/> |
|
||||
</div> |
|
||||
</div> |
|
||||
<div class="oe_span6"> |
|
||||
<p class="oe_mt32"> |
|
||||
Click on the image and see how popup is appear. |
|
||||
</p> |
|
||||
</div> |
|
||||
</div> |
|
||||
</section> |
|
||||
|
|
||||
<section class="oe_container"> |
|
||||
<div class="oe_row oe_spaced"> |
|
||||
<div class="oe_span6"> |
|
||||
<p class="oe_mt32"> |
|
||||
Moreover, you can download it to your device by clicking on the "Download" button if needed. |
|
||||
</p> |
|
||||
</div> |
|
||||
<div class="oe_span6"> |
|
||||
<div class="oe_row_img oe_centered"> |
|
||||
<img class="oe_demo oe_picture oe_screenshot" src="download.png"/> |
|
||||
</div> |
|
||||
</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:apps@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:apps@it-projects.info">apps@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> |
|
Before Width: 365 | Height: 382 | Size: 150 KiB |
@ -1,429 +0,0 @@ |
|||||
/* |
|
||||
|
|
||||
arcticModal — jQuery plugin |
|
||||
Version: 0.3 |
|
||||
Author: Sergey Predvoditelev (sergey.predvoditelev@gmail.com) |
|
||||
Company: Arctic Laboratory (http://arcticlab.ru/)
|
|
||||
|
|
||||
Docs & Examples: http://arcticlab.ru/arcticmodal/
|
|
||||
|
|
||||
*/ |
|
||||
(function($) { |
|
||||
|
|
||||
|
|
||||
var default_options = { |
|
||||
|
|
||||
type: 'html', // ajax или html
|
|
||||
content: '', |
|
||||
url: '', |
|
||||
ajax: {}, |
|
||||
ajax_request: null, |
|
||||
|
|
||||
closeOnEsc: true, |
|
||||
closeOnOverlayClick: true, |
|
||||
|
|
||||
clone: false, |
|
||||
|
|
||||
overlay: { |
|
||||
block: undefined, |
|
||||
tpl: '<div class="arcticmodal-overlay"></div>', |
|
||||
css: { |
|
||||
backgroundColor: '#000', |
|
||||
opacity: .6 |
|
||||
} |
|
||||
}, |
|
||||
|
|
||||
container: { |
|
||||
block: undefined, |
|
||||
tpl: '<div class="arcticmodal-container"><table class="arcticmodal-container_i"><tr><td class="arcticmodal-container_i2"></td></tr></table></div>' |
|
||||
}, |
|
||||
|
|
||||
wrap: undefined, |
|
||||
body: undefined, |
|
||||
|
|
||||
errors: { |
|
||||
tpl: '<div class="arcticmodal-error arcticmodal-close"></div>', |
|
||||
autoclose_delay: 2000, |
|
||||
ajax_unsuccessful_load: 'Error' |
|
||||
}, |
|
||||
|
|
||||
openEffect: { |
|
||||
type: 'fade', |
|
||||
speed: 400 |
|
||||
}, |
|
||||
closeEffect: { |
|
||||
type: 'fade', |
|
||||
speed: 400 |
|
||||
}, |
|
||||
|
|
||||
beforeOpen: $.noop, |
|
||||
afterOpen: $.noop, |
|
||||
beforeClose: $.noop, |
|
||||
afterClose: $.noop, |
|
||||
afterLoading: $.noop, |
|
||||
afterLoadingOnShow: $.noop, |
|
||||
errorLoading: $.noop |
|
||||
|
|
||||
}; |
|
||||
|
|
||||
|
|
||||
var modalID = 0; |
|
||||
var modals = $([]); |
|
||||
|
|
||||
|
|
||||
var utils = { |
|
||||
|
|
||||
|
|
||||
// Определяет произошло ли событие e вне блока block
|
|
||||
isEventOut: function(blocks, e) { |
|
||||
var r = true; |
|
||||
$(blocks).each(function() { |
|
||||
if ($(e.target).get(0)==$(this).get(0)) r = false; |
|
||||
if ($(e.target).closest('HTML', $(this).get(0)).length==0) r = false; |
|
||||
}); |
|
||||
return r; |
|
||||
} |
|
||||
|
|
||||
|
|
||||
}; |
|
||||
|
|
||||
|
|
||||
var modal = { |
|
||||
|
|
||||
|
|
||||
// Возвращает элемент, которым был вызван плагин
|
|
||||
getParentEl: function(el) { |
|
||||
var r = $(el); |
|
||||
if (r.data('arcticmodal')) return r; |
|
||||
r = $(el).closest('.arcticmodal-container').data('arcticmodalParentEl'); |
|
||||
if (r) return r; |
|
||||
return false; |
|
||||
}, |
|
||||
|
|
||||
|
|
||||
// Переход
|
|
||||
transition: function(el, action, options, callback) { |
|
||||
callback = callback==undefined ? $.noop : callback; |
|
||||
switch (options.type) { |
|
||||
case 'fade': |
|
||||
action=='show' ? el.fadeIn(options.speed, callback) : el.fadeOut(options.speed, callback); |
|
||||
break; |
|
||||
case 'none': |
|
||||
action=='show' ? el.show() : el.hide(); |
|
||||
callback(); |
|
||||
break; |
|
||||
} |
|
||||
}, |
|
||||
|
|
||||
|
|
||||
// Подготвка содержимого окна
|
|
||||
prepare_body: function(D, $this) { |
|
||||
|
|
||||
// Обработчик закрытия
|
|
||||
$('.arcticmodal-close', D.body).unbind('click.arcticmodal').bind('click.arcticmodal', function() { |
|
||||
$this.arcticmodal('close'); |
|
||||
return false; |
|
||||
}); |
|
||||
|
|
||||
}, |
|
||||
|
|
||||
|
|
||||
// Инициализация элемента
|
|
||||
init_el: function($this, options) { |
|
||||
var D = $this.data('arcticmodal'); |
|
||||
if (D) return; |
|
||||
|
|
||||
D = options; |
|
||||
modalID++; |
|
||||
D.modalID = modalID; |
|
||||
|
|
||||
// Overlay
|
|
||||
D.overlay.block = $(D.overlay.tpl); |
|
||||
D.overlay.block.css(D.overlay.css); |
|
||||
|
|
||||
// Container
|
|
||||
D.container.block = $(D.container.tpl); |
|
||||
|
|
||||
// BODY
|
|
||||
D.body = $('.arcticmodal-container_i2', D.container.block); |
|
||||
if (options.clone) { |
|
||||
D.body.html($this.clone(true)); |
|
||||
} else { |
|
||||
$this.before('<div id="arcticmodalReserve' + D.modalID + '" style="display: none" />'); |
|
||||
D.body.html($this); |
|
||||
} |
|
||||
|
|
||||
// Подготовка содержимого
|
|
||||
modal.prepare_body(D, $this); |
|
||||
|
|
||||
// Закрытие при клике на overlay
|
|
||||
if (D.closeOnOverlayClick) |
|
||||
D.overlay.block.add(D.container.block).click(function(e) { |
|
||||
if (utils.isEventOut($('>*', D.body), e)) |
|
||||
$this.arcticmodal('close'); |
|
||||
}); |
|
||||
|
|
||||
// Запомним настройки
|
|
||||
D.container.block.data('arcticmodalParentEl', $this); |
|
||||
$this.data('arcticmodal', D); |
|
||||
modals = $.merge(modals, $this); |
|
||||
|
|
||||
// Показать
|
|
||||
$.proxy(actions.show, $this)(); |
|
||||
if (D.type=='html') return $this; |
|
||||
|
|
||||
// Ajax-загрузка
|
|
||||
if (D.ajax.beforeSend!=undefined) { |
|
||||
var fn_beforeSend = D.ajax.beforeSend; |
|
||||
delete D.ajax.beforeSend; |
|
||||
} |
|
||||
if (D.ajax.success!=undefined) { |
|
||||
var fn_success = D.ajax.success; |
|
||||
delete D.ajax.success; |
|
||||
} |
|
||||
if (D.ajax.error!=undefined) { |
|
||||
var fn_error = D.ajax.error; |
|
||||
delete D.ajax.error; |
|
||||
} |
|
||||
var o = $.extend(true, { |
|
||||
url: D.url, |
|
||||
beforeSend: function() { |
|
||||
if (fn_beforeSend==undefined) { |
|
||||
D.body.html('<div class="arcticmodal-loading" />'); |
|
||||
} else { |
|
||||
fn_beforeSend(D, $this); |
|
||||
} |
|
||||
}, |
|
||||
success: function(responce) { |
|
||||
|
|
||||
// Событие после загрузки до показа содержимого
|
|
||||
$this.trigger('afterLoading'); |
|
||||
D.afterLoading(D, $this, responce); |
|
||||
|
|
||||
if (fn_success==undefined) { |
|
||||
D.body.html(responce); |
|
||||
} else { |
|
||||
fn_success(D, $this, responce); |
|
||||
} |
|
||||
modal.prepare_body(D, $this); |
|
||||
|
|
||||
// Событие после загрузки после отображения содержимого
|
|
||||
$this.trigger('afterLoadingOnShow'); |
|
||||
D.afterLoadingOnShow(D, $this, responce); |
|
||||
|
|
||||
}, |
|
||||
error: function() { |
|
||||
|
|
||||
// Событие при ошибке загрузки
|
|
||||
$this.trigger('errorLoading'); |
|
||||
D.errorLoading(D, $this); |
|
||||
|
|
||||
if (fn_error==undefined) { |
|
||||
D.body.html(D.errors.tpl); |
|
||||
$('.arcticmodal-error', D.body).html(D.errors.ajax_unsuccessful_load); |
|
||||
$('.arcticmodal-close', D.body).click(function() { |
|
||||
$this.arcticmodal('close'); |
|
||||
return false; |
|
||||
}); |
|
||||
if (D.errors.autoclose_delay) |
|
||||
setTimeout(function() { |
|
||||
$this.arcticmodal('close'); |
|
||||
}, D.errors.autoclose_delay); |
|
||||
} else { |
|
||||
fn_error(D, $this); |
|
||||
} |
|
||||
} |
|
||||
}, D.ajax); |
|
||||
D.ajax_request = $.ajax(o); |
|
||||
|
|
||||
// Запомнить настройки
|
|
||||
$this.data('arcticmodal', D); |
|
||||
|
|
||||
}, |
|
||||
|
|
||||
|
|
||||
// Инициализация
|
|
||||
init: function(options) { |
|
||||
options = $.extend(true, {}, default_options, options); |
|
||||
if ($.isFunction(this)) { |
|
||||
if (options==undefined) { |
|
||||
$.error('jquery.arcticmodal: Uncorrect parameters'); |
|
||||
return; |
|
||||
} |
|
||||
if (options.type=='') { |
|
||||
$.error('jquery.arcticmodal: Don\'t set parameter "type"'); |
|
||||
return; |
|
||||
} |
|
||||
switch (options.type) { |
|
||||
case 'html': |
|
||||
if (options.content=='') { |
|
||||
$.error('jquery.arcticmodal: Don\'t set parameter "content"'); |
|
||||
return |
|
||||
} |
|
||||
var c = options.content; |
|
||||
options.content = ''; |
|
||||
|
|
||||
return modal.init_el($(c), options); |
|
||||
break; |
|
||||
case 'ajax': |
|
||||
if (options.url=='') { |
|
||||
$.error('jquery.arcticmodal: Don\'t set parameter "url"'); |
|
||||
return; |
|
||||
} |
|
||||
return modal.init_el($('<div />'), options); |
|
||||
break; |
|
||||
} |
|
||||
} else { |
|
||||
return this.each(function() { |
|
||||
modal.init_el($(this), $.extend(true, {}, options)); |
|
||||
}); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
|
|
||||
}; |
|
||||
|
|
||||
|
|
||||
var actions = { |
|
||||
|
|
||||
|
|
||||
// Показать
|
|
||||
show: function() { |
|
||||
var $this = modal.getParentEl(this); |
|
||||
if ($this===false) { |
|
||||
$.error('jquery.arcticmodal: Uncorrect call'); |
|
||||
return; |
|
||||
} |
|
||||
var D = $this.data('arcticmodal'); |
|
||||
|
|
||||
// Добавить overlay и container
|
|
||||
D.overlay.block.hide(); |
|
||||
D.container.block.hide(); |
|
||||
$('BODY').append(D.overlay.block); |
|
||||
$('BODY').append(D.container.block); |
|
||||
|
|
||||
// Событие
|
|
||||
D.beforeOpen(D, $this); |
|
||||
$this.trigger('beforeOpen'); |
|
||||
|
|
||||
// Wrap
|
|
||||
if (D.wrap.css('overflow')!='hidden') { |
|
||||
D.wrap.data('arcticmodalOverflow', D.wrap.css('overflow')); |
|
||||
var w1 = D.wrap.outerWidth(true); |
|
||||
D.wrap.css('overflow', 'hidden'); |
|
||||
var w2 = D.wrap.outerWidth(true); |
|
||||
if (w2!=w1) |
|
||||
D.wrap.css('marginRight', (w2 - w1) + 'px'); |
|
||||
} |
|
||||
|
|
||||
// Скрыть предыдущие оверлеи
|
|
||||
modals.not($this).each(function() { |
|
||||
var d = $(this).data('arcticmodal'); |
|
||||
d.overlay.block.hide(); |
|
||||
}); |
|
||||
|
|
||||
// Показать
|
|
||||
modal.transition(D.overlay.block, 'show', modals.length>1 ? {type: 'none'} : D.openEffect); |
|
||||
modal.transition(D.container.block, 'show', modals.length>1 ? {type: 'none'} : D.openEffect, function() { |
|
||||
D.afterOpen(D, $this); |
|
||||
$this.trigger('afterOpen'); |
|
||||
}); |
|
||||
|
|
||||
return $this; |
|
||||
}, |
|
||||
|
|
||||
|
|
||||
// Закрыть
|
|
||||
close: function() { |
|
||||
if ($.isFunction(this)) { |
|
||||
modals.each(function() { |
|
||||
$(this).arcticmodal('close'); |
|
||||
}); |
|
||||
} else { |
|
||||
return this.each(function() { |
|
||||
var $this = modal.getParentEl(this); |
|
||||
if ($this===false) { |
|
||||
$.error('jquery.arcticmodal: Uncorrect call'); |
|
||||
return; |
|
||||
} |
|
||||
var D = $this.data('arcticmodal'); |
|
||||
|
|
||||
// Событие перед закрытием
|
|
||||
if (D.beforeClose(D, $this)===false) return; |
|
||||
$this.trigger('beforeClose'); |
|
||||
|
|
||||
// Показать предыдущие оверлеи
|
|
||||
modals.not($this).last().each(function() { |
|
||||
var d = $(this).data('arcticmodal'); |
|
||||
d.overlay.block.show(); |
|
||||
}); |
|
||||
|
|
||||
modal.transition(D.overlay.block, 'hide', modals.length>1 ? {type: 'none'} : D.closeEffect); |
|
||||
modal.transition(D.container.block, 'hide', modals.length>1 ? {type: 'none'} : D.closeEffect, function() { |
|
||||
|
|
||||
// Событие после закрытия
|
|
||||
D.afterClose(D, $this); |
|
||||
$this.trigger('afterClose'); |
|
||||
|
|
||||
// Если не клонировали - вернём на место
|
|
||||
if (!D.clone) |
|
||||
$('#arcticmodalReserve' + D.modalID).replaceWith(D.body.find('>*')); |
|
||||
|
|
||||
D.overlay.block.remove(); |
|
||||
D.container.block.remove(); |
|
||||
$this.data('arcticmodal', null); |
|
||||
if (!$('.arcticmodal-container').length) { |
|
||||
if (D.wrap.data('arcticmodalOverflow')) |
|
||||
D.wrap.css('overflow', D.wrap.data('arcticmodalOverflow')); |
|
||||
D.wrap.css('marginRight', 0); |
|
||||
} |
|
||||
|
|
||||
}); |
|
||||
|
|
||||
if (D.type=='ajax') |
|
||||
D.ajax_request.abort(); |
|
||||
|
|
||||
modals = modals.not($this); |
|
||||
}); |
|
||||
} |
|
||||
}, |
|
||||
|
|
||||
|
|
||||
// Установить опции по-умолчанию
|
|
||||
setDefault: function(options) { |
|
||||
$.extend(true, default_options, options); |
|
||||
} |
|
||||
|
|
||||
|
|
||||
}; |
|
||||
|
|
||||
|
|
||||
$(function() { |
|
||||
default_options.wrap = $((document.all && !document.querySelector) ? 'html' : 'body'); |
|
||||
}); |
|
||||
|
|
||||
|
|
||||
// Закрытие при нажатии Escape
|
|
||||
$(document).bind('keyup.arcticmodal', function(e) { |
|
||||
var m = modals.last(); |
|
||||
if (!m.length) return; |
|
||||
var D = m.data('arcticmodal'); |
|
||||
if (D.closeOnEsc && (e.keyCode===27)) |
|
||||
m.arcticmodal('close'); |
|
||||
}); |
|
||||
|
|
||||
|
|
||||
$.arcticmodal = $.fn.arcticmodal = function(method) { |
|
||||
|
|
||||
if (actions[method]) { |
|
||||
return actions[method].apply(this, Array.prototype.slice.call(arguments, 1)); |
|
||||
} else if (typeof method==='object' || !method) { |
|
||||
return modal.init.apply(this, arguments); |
|
||||
} else { |
|
||||
$.error('jquery.arcticmodal: Method ' + method + ' does not exist'); |
|
||||
} |
|
||||
|
|
||||
}; |
|
||||
|
|
||||
|
|
||||
})(jQuery); |
|
@ -1,8 +0,0 @@ |
|||||
.arcticmodal-overlay, |
|
||||
.arcticmodal-container { position: fixed; left: 0; top: 0; right: 0; bottom: 0; z-index: 1010; } |
|
||||
.arcticmodal-container { overflow: auto; margin: 0; padding: 0; border: 0; border-collapse: collapse; } |
|
||||
*:first-child+html .arcticmodal-container { height: 100% } |
|
||||
.arcticmodal-container_i { height: 100%; margin: 0 auto; } |
|
||||
.arcticmodal-container_i2 { padding: 24px; margin: 0; border: 0; vertical-align: middle; padding-top: 50px;} |
|
||||
.arcticmodal-error { padding: 20px; border-radius: 10px; background: #000; color: #fff; } |
|
||||
.arcticmodal-loading { width: 80px; height: 80px; border-radius: 10px; background: #000 url(/mail_attachment_popup/static/src/img/loading.gif) no-repeat 50% 50%; } |
|
@ -1,11 +0,0 @@ |
|||||
.box-modal { |
|
||||
position: relative; |
|
||||
padding: 16px; |
|
||||
background: #fff; |
|
||||
color: #3c3c3c; |
|
||||
font: 14px/18px Arial, "Helvetica CY", "Nimbus Sans L", sans-serif; |
|
||||
box-shadow: 0 0 0 6px rgba(153, 153, 153, .3); |
|
||||
border-radius: 6px; |
|
||||
} |
|
||||
.box-modal_close { position: absolute; right: -25px; top: -25px; font-size: 30px; line-height: 15px; color: #ffffff; cursor: pointer; } |
|
||||
.box-modal_close:hover { color: #B1B1B1; } |
|
@ -1,16 +0,0 @@ |
|||||
.g-hidden { |
|
||||
display: none; |
|
||||
} |
|
||||
.box-modal img { |
|
||||
max-width: 900px; |
|
||||
width: 100%; |
|
||||
} |
|
||||
.box-modal-li li { |
|
||||
list-style-type: none; |
|
||||
} |
|
||||
.box-modal-li { |
|
||||
padding-left: 0; |
|
||||
} |
|
||||
.o_attachment .o_image { |
|
||||
cursor: pointer; |
|
||||
} |
|
Before Width: 32 | Height: 32 | Size: 3.1 KiB |
@ -1,29 +0,0 @@ |
|||||
<?xml version="1.0" encoding="UTF-8"?> |
|
||||
<template> |
|
||||
<t t-extend="mail.Attachment"> |
|
||||
<t t-jquery="div[t-att-title='attachment.name'] .o_image" t-operation="replace"> |
|
||||
<t t-if="attachment.mimetype and attachment.mimetype.search('image/') !== -1"> |
|
||||
<span class="m-dotted" t-attf-onclick="$('#ImageModal{{ attachment.id }}').arcticmodal()"> |
|
||||
<div class="o_image" target="_blank" t-att-data-mimetype="attachment.mimetype" t-attf-data-src="/web/image/#{attachment.id}/100x80"> |
|
||||
<span class='o_attachment_name'><t t-esc='attachment.name'/></span> |
|
||||
</div> |
|
||||
</span> |
|
||||
<div class="g-hidden"> |
|
||||
<div class="box-modal" t-attf-id="ImageModal{{ attachment.id }}"> |
|
||||
<div class="box-modal_close arcticmodal-close">X</div> |
|
||||
<img t-att-data-mimetype="attachment.mimetype" t-attf-src="/web/image/#{attachment.id}"></img> |
|
||||
<ul class="box-modal-li"> |
|
||||
<li><span class='o_attachment_name'><t t-esc='attachment.name'/></span></li> |
|
||||
<li><span class='oe_download_original_img'><a t-att-href='attachment.url' target="_blank">Download</a></span></li> |
|
||||
</ul> |
|
||||
</div> |
|
||||
</div> |
|
||||
</t> |
|
||||
<t t-if="! (attachment.mimetype and attachment.mimetype.search('image/') !== -1)"> |
|
||||
<a class="o_image" t-att-href='attachment.url' target="_blank" t-att-data-mimetype="attachment.mimetype" t-attf-data-src="/web/image/#{attachment.id}/100x80"> |
|
||||
<span class='o_attachment_name'><t t-esc='attachment.name'/></span> |
|
||||
</a> |
|
||||
</t> |
|
||||
</t> |
|
||||
</t> |
|
||||
</template> |
|
@ -1,13 +0,0 @@ |
|||||
<?xml version="1.0" encoding="utf-8"?> |
|
||||
<openerp> |
|
||||
<data> |
|
||||
<template id="assets_backend" name="mail attachment popup assets" inherit_id="web.assets_backend"> |
|
||||
<xpath expr="." position="inside"> |
|
||||
<link rel="stylesheet" href="/mail_attachment_popup/static/src/css/jquery.arcticmodal.css"/> |
|
||||
<link rel="stylesheet" href="/mail_attachment_popup/static/src/css/simple.css"/> |
|
||||
<link rel="stylesheet" href="/mail_attachment_popup/static/src/css/styles.css"/> |
|
||||
<script type="text/javascript" src="/mail_attachment_popup/static/lib/js/jquery.arcticmodal.js"></script> |
|
||||
</xpath> |
|
||||
</template> |
|
||||
</data> |
|
||||
</openerp> |
|
@ -1,4 +1,3 @@ |
|||||
# -*- coding: utf-8 -*- |
|
||||
|
|
||||
from . import models |
from . import models |
||||
from . import controllers |
from . import controllers |
@ -1,4 +1,18 @@ |
|||||
Mail Base |
|
||||
========= |
|
||||
|
========================= |
||||
|
Mail Base |
||||
|
========================= |
||||
|
|
||||
To use this module you need either install module that depends on it or create new module. |
|
||||
|
Installation |
||||
|
============ |
||||
|
|
||||
|
* `Install <https://odoo-development.readthedocs.io/en/latest/odoo/usage/install-module.html>`__ this module in a usual way |
||||
|
|
||||
|
Configuration |
||||
|
============= |
||||
|
|
||||
|
This module does not require special configuration. |
||||
|
|
||||
|
Usage |
||||
|
===== |
||||
|
|
||||
|
* To use this module you need either install module that depends on it or create new module. |
1294
mail_base/static/lib/base.js
File diff suppressed because it is too large
View File
@ -0,0 +1,2 @@ |
|||||
|
|
||||
|
from . import test_default |
@ -0,0 +1,16 @@ |
|||||
|
import odoo.tests |
||||
|
|
||||
|
|
||||
|
@odoo.tests.common.at_install(False) |
||||
|
@odoo.tests.common.post_install(True) |
||||
|
class TestUi(odoo.tests.HttpCase): |
||||
|
|
||||
|
def test_01_mail_base(self): |
||||
|
# wait till page loaded |
||||
|
code = """ |
||||
|
setTimeout(function () { |
||||
|
console.log('ok'); |
||||
|
}, 1000); |
||||
|
""" |
||||
|
link = '/web#action=%s' % self.ref('mail.mail_channel_action_client_chat') |
||||
|
self.phantom_js(link, code, "odoo.__DEBUG__.services['mail_base.base']", login="admin") |
@ -1,2 +1 @@ |
|||||
# -*- coding: utf-8 -*- |
|
||||
from . import models |
from . import models |
@ -1,2 +1 @@ |
|||||
# -*- coding: utf-8 -*- |
|
||||
from . import mail_fix_553 |
from . import mail_fix_553 |
@ -1,10 +1,49 @@ |
|||||
Mail relocation |
|
||||
=============== |
|
||||
|
.. image:: https://img.shields.io/badge/license-LGPL--3-blue.png |
||||
|
:target: https://www.gnu.org/licenses/lgpl |
||||
|
:alt: License: LGPL-3 |
||||
|
|
||||
Demo: http://runbot.it-projects.info/demo/mail-addons/9.0 |
|
||||
|
================= |
||||
|
Mail Relocation |
||||
|
================= |
||||
|
|
||||
Description: https://www.odoo.com/apps/modules/9.0/mail_move_message/ |
|
||||
|
The module allows to relocate messages between models |
||||
|
|
||||
|
Credits |
||||
|
======= |
||||
|
|
||||
|
Contributors |
||||
|
------------ |
||||
|
* `Ivan Yelizariev <https://it-projects.info/team/yelizariev>`__ |
||||
|
|
||||
|
Sponsors |
||||
|
-------- |
||||
|
* `IT-Projects LLC <https://it-projects.info>`__ |
||||
|
|
||||
|
Maintainers |
||||
|
----------- |
||||
|
* `IT-Projects LLC <https://it-projects.info>`__ |
||||
|
|
||||
|
To get a guaranteed support |
||||
|
you are kindly requested to purchase the module |
||||
|
at `odoo apps store <https://apps.odoo.com/apps/modules/11.0/mail_move_message/>`__. |
||||
|
|
||||
|
Thank you for understanding! |
||||
|
|
||||
|
`IT-Projects Team <https://www.it-projects.info/team>`__ |
||||
|
|
||||
|
Further information |
||||
|
=================== |
||||
|
|
||||
|
Demo: http://runbot.it-projects.info/demo/mail-addons/11.0 |
||||
|
|
||||
|
HTML Description: https://apps.odoo.com/apps/modules/11.0/mail_move_message/ |
||||
|
|
||||
|
Usage instructions: `<doc/index.rst>`_ |
||||
|
|
||||
|
Changelog: `<doc/changelog.rst>`_ |
||||
|
|
||||
|
Notifications on updates: `via Atom <https://github.com/it-projects-llc/mail-addons/commits/11.0/mail_move_message.atom>`_, `by Email <https://blogtrottr.com/?subscribe=https://github.com/it-projects-llc/mail-addons/commits/11.0/mail_move_message.atom>`_ |
||||
|
|
||||
Further information and discussion: http://yelizariev.github.io/odoo/module/2015/04/10/mail-relocation.html |
Further information and discussion: http://yelizariev.github.io/odoo/module/2015/04/10/mail-relocation.html |
||||
|
|
||||
Tested on Odoo 8.0 d023c079ed86468436f25da613bf486a4a17d625 |
|
||||
|
Tested on Odoo 11.0 e9454e79e27d0b85546132cbe00b391e974c66bf |
@ -1,3 +1,4 @@ |
|||||
# -*- coding: utf-8 -*- |
|
||||
|
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html). |
||||
|
|
||||
from . import controllers |
from . import controllers |
||||
from . import mail_move_message_models |
from . import mail_move_message_models |
@ -1,2 +1,3 @@ |
|||||
# -*- coding: utf-8 -*- |
|
||||
|
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html). |
||||
|
|
||||
from . import main |
from . import main |
@ -1,9 +1,11 @@ |
|||||
<?xml version="1.0"?> |
<?xml version="1.0"?> |
||||
<openerp> |
|
||||
<data noupdate="1"> |
|
||||
|
<!--# Copyright 2016 Ildar Nasyrov <https://it-projects.info/team/iledarn> |
||||
|
# Copyright 2017 Ivan Yelizariev <https://it-projects.info/team/yelizariev> |
||||
|
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html).--> |
||||
|
|
||||
|
<odoo> |
||||
<record id="mail_relocation_models" model="ir.config_parameter"> |
<record id="mail_relocation_models" model="ir.config_parameter"> |
||||
<field name="key">mail_relocation_models</field> |
<field name="key">mail_relocation_models</field> |
||||
<field name="value">crm.lead,project.task</field> |
<field name="value">crm.lead,project.task</field> |
||||
</record> |
</record> |
||||
</data> |
|
||||
</openerp> |
|
||||
|
</odoo> |
@ -0,0 +1,35 @@ |
|||||
|
================= |
||||
|
Mail Relocation |
||||
|
================= |
||||
|
|
||||
|
Installation |
||||
|
============ |
||||
|
|
||||
|
* `Install <https://odoo-development.readthedocs.io/en/latest/odoo/usage/install-module.html>`__ this module in a usual way |
||||
|
|
||||
|
Configuration |
||||
|
============= |
||||
|
|
||||
|
* Open ``[[ Settings ]] >> Mail Relocation`` menu |
||||
|
* In **Model** field add models to be used for message relocation |
||||
|
* Check the box **[x] Move Followers** to move followers by default when relocation |
||||
|
|
||||
|
Usage |
||||
|
===== |
||||
|
|
||||
|
Move message |
||||
|
------------ |
||||
|
|
||||
|
* Open ``[[ Discuss ]] >> Inbox`` menu |
||||
|
* Click on icon of two cross arrows |
||||
|
* Select a record you need |
||||
|
* Click **Move** |
||||
|
RESULT: The message has been moved to the record selected. |
||||
|
|
||||
|
Move to origin |
||||
|
-------------- |
||||
|
|
||||
|
* Open the record where the message was moved to |
||||
|
* Click on the two cross arrows icon highlighted as red |
||||
|
* Check the box **[x] Move to origin** |
||||
|
RESULT: The message has been returned back to the original record. |
Before Width: 1012 | Height: 546 | Size: 39 KiB After Width: 667 | Height: 446 | Size: 32 KiB |
Before Width: 149 | Height: 149 | Size: 1.5 KiB After Width: 100 | Height: 100 | Size: 2.1 KiB |
Before Width: 1054 | Height: 562 | Size: 57 KiB After Width: 667 | Height: 446 | Size: 32 KiB |
Before Width: 904 | Height: 482 | Size: 42 KiB After Width: 658 | Height: 465 | Size: 44 KiB |
@ -0,0 +1,3 @@ |
|||||
|
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html). |
||||
|
from . import test_mail_move |
||||
|
|
@ -0,0 +1,52 @@ |
|||||
|
# Copyright 2018 Kolushov Alexandr <https://it-projects.info/team/KolushovAlexandr> |
||||
|
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html). |
||||
|
|
||||
|
import odoo.tests |
||||
|
from odoo.api import Environment |
||||
|
|
||||
|
|
||||
|
@odoo.tests.common.at_install(True) |
||||
|
@odoo.tests.common.post_install(True) |
||||
|
class TestUi(odoo.tests.HttpCase): |
||||
|
|
||||
|
def test_create_new_partner_and_move_message(self): |
||||
|
env = Environment(self.registry.test_cr, self.uid, {}) |
||||
|
# needed because tests are run before the module is marked as |
||||
|
# installed. In js web will only load qweb coming from modules |
||||
|
# that are returned by the backend in module_boot. Without |
||||
|
# this you end up with js, css but no qweb. |
||||
|
env['ir.module.module'].search([('name', '=', 'mail_move_message')], limit=1).state = 'installed' |
||||
|
self.registry.cursor().release() |
||||
|
|
||||
|
# updating models, to be able relocate messages to a partner at_install |
||||
|
config_parameters = self.env["ir.config_parameter"].sudo() |
||||
|
config_parameters.set_param("mail_relocation_models", "crm.lead,project.task,res.partner") |
||||
|
|
||||
|
code = """ |
||||
|
var delayed_button_click = function(delay, button){ |
||||
|
setTimeout(function(){ |
||||
|
if (button.length) { |
||||
|
return button.click(); |
||||
|
} |
||||
|
return console.log('error', 'There is no element with the next selector: ' + button.selector); |
||||
|
}, delay); |
||||
|
}; |
||||
|
var delay = 1000; |
||||
|
var message = $('.o_thread_message_core:contains("virginie")'); |
||||
|
var relocate = message.find('.o_thread_icons .fa-exchange'); |
||||
|
delayed_button_click(delay, relocate); |
||||
|
// form is opened |
||||
|
|
||||
|
var create_partner_button = $('button[special="quick_create"]'); |
||||
|
delayed_button_click(delay, create_partner_button); |
||||
|
// partner creation wizard is opened |
||||
|
|
||||
|
var save_button = $('.modal-content .btn-primary:contains("Save")'); |
||||
|
delayed_button_click(delay, save_button); |
||||
|
|
||||
|
var move_button = $('.btn-sm.oe_highlight:contains("Move")'); |
||||
|
delayed_button_click(delay, move_button); |
||||
|
console.log('ok') |
||||
|
""" |
||||
|
|
||||
|
self.phantom_js('/web', code, login="admin", ready="$('.o_thread_icons').length") |
@ -0,0 +1,62 @@ |
|||||
|
.. image:: https://img.shields.io/badge/license-LGPL--3-blue.png |
||||
|
:target: https://www.gnu.org/licenses/lgpl |
||||
|
:alt: License: LGPL-3 |
||||
|
|
||||
|
=========================================== |
||||
|
Email Addresses and Templates per Website |
||||
|
=========================================== |
||||
|
|
||||
|
Mail-related stuff for multi-website support |
||||
|
|
||||
|
* Makes following field in ``res.users`` website-dependent: |
||||
|
|
||||
|
* ``email`` |
||||
|
* ``signature`` |
||||
|
|
||||
|
* Makes following fields in ``mail.template`` website-dependent: |
||||
|
|
||||
|
* ``body_html`` |
||||
|
* ``mail_server_id`` |
||||
|
* ``report_template`` |
||||
|
|
||||
|
* Overrides ``mail.template``'s ``render_template`` method to add ``website`` |
||||
|
variable. It may cause incompatibility with other modules that redefine that |
||||
|
method too. |
||||
|
|
||||
|
Credits |
||||
|
======= |
||||
|
|
||||
|
Contributors |
||||
|
------------ |
||||
|
* `Ivan Yelizariev <https://it-projects.info/team/yelizariev>`__ |
||||
|
|
||||
|
Sponsors |
||||
|
-------- |
||||
|
* `e-thos SSII <http://www.e-thos.fr/>`__ |
||||
|
|
||||
|
Maintainers |
||||
|
----------- |
||||
|
* `IT-Projects LLC <https://it-projects.info>`__ |
||||
|
|
||||
|
To get a guaranteed support |
||||
|
you are kindly requested to purchase the module |
||||
|
at `odoo apps store <https://apps.odoo.com/apps/modules/11.0/mail_multi_website/>`__. |
||||
|
|
||||
|
Thank you for understanding! |
||||
|
|
||||
|
`IT-Projects Team <https://www.it-projects.info/team>`__ |
||||
|
|
||||
|
Further information |
||||
|
=================== |
||||
|
|
||||
|
Demo: http://runbot.it-projects.info/demo/mail-addons/11.0 |
||||
|
|
||||
|
HTML Description: https://apps.odoo.com/apps/modules/11.0/mail_multi_website/ |
||||
|
|
||||
|
Usage instructions: `<doc/index.rst>`_ |
||||
|
|
||||
|
Changelog: `<doc/changelog.rst>`_ |
||||
|
|
||||
|
Notifications on updates: `via Atom <https://github.com/it-projects-llc/mail-addons/commits/11.0/mail_multi_website.atom>`_, `by Email <https://blogtrottr.com/?subscribe=https://github.com/it-projects-llc/mail-addons/commits/11.0/mail_multi_website.atom>`_ |
||||
|
|
||||
|
Tested on Odoo 11.0 4d0a1330e05bd688265bea14df4ad12838f9f2d7 |
@ -0,0 +1,40 @@ |
|||||
|
# Copyright 2018 Ivan Yelizariev <https://it-projects.info/team/yelizariev> |
||||
|
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html). |
||||
|
from . import models |
||||
|
from . import wizard |
||||
|
from .tests import test_mail_model |
||||
|
|
||||
|
|
||||
|
def post_init_hook(cr, registry): |
||||
|
from odoo import api, SUPERUSER_ID |
||||
|
|
||||
|
env = api.Environment(cr, SUPERUSER_ID, {}) |
||||
|
|
||||
|
env.cr.execute("ALTER TABLE res_users ADD COLUMN email_multi_website VARCHAR") |
||||
|
|
||||
|
# fill new email column with values from partner |
||||
|
for user in env['res.users'].with_context(active_test=False).search([]): |
||||
|
email = user.partner_id.email |
||||
|
if email: |
||||
|
user._force_default('email_multi_website', email) |
||||
|
|
||||
|
|
||||
|
def uninstall_hook(cr, registry): |
||||
|
from odoo import api, SUPERUSER_ID |
||||
|
|
||||
|
env = api.Environment(cr, SUPERUSER_ID, {}) |
||||
|
|
||||
|
# remove properties |
||||
|
field_ids = [ |
||||
|
env.ref('base.field_res_users_email').id, |
||||
|
env.ref('base.field_res_users_signature').id, |
||||
|
env.ref('mail.field_mail_template_body_html').id, |
||||
|
env.ref('mail.field_mail_template_mail_server_id').id, |
||||
|
env.ref('mail.field_mail_template_report_template').id, |
||||
|
] |
||||
|
env['ir.property'].search([('fields_id', 'in', field_ids)]).unlink() |
||||
|
|
||||
|
# copy emails from partner to user |
||||
|
cr.execute("SELECT partner_id,email_multi_website FROM res_users") |
||||
|
for partner_id, default_email in cr.fetchall(): |
||||
|
env['res.partner'].browse(partner_id).email = default_email |
@ -0,0 +1,51 @@ |
|||||
|
# Copyright 2018 Ivan Yelizariev <https://it-projects.info/team/yelizariev> |
||||
|
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html). |
||||
|
{ |
||||
|
"name": """Email Addresses and Templates per Website""", |
||||
|
"summary": """Use single Backend to manage several Websites""", |
||||
|
"category": "Discuss", |
||||
|
"live_test_url": "http://apps.it-projects.info/shop/product/website-multi-company?version=11.0", |
||||
|
"images": ["images/main.jpg"], |
||||
|
"version": "11.0.1.0.0", |
||||
|
"application": False, |
||||
|
|
||||
|
"author": "IT-Projects LLC, Ivan Yelizariev", |
||||
|
"support": "apps@it-projects.info", |
||||
|
"website": "https://it-projects.info/team/yelizariev", |
||||
|
"license": "LGPL-3", |
||||
|
"price": 230.00, |
||||
|
"currency": "EUR", |
||||
|
|
||||
|
"depends": [ |
||||
|
"ir_config_parameter_multi_company", |
||||
|
"web_website", |
||||
|
"mail", |
||||
|
], |
||||
|
"external_dependencies": {"python": [], "bin": []}, |
||||
|
"data": [ |
||||
|
"views/website_views.xml", |
||||
|
], |
||||
|
"demo": [ |
||||
|
], |
||||
|
"qweb": [ |
||||
|
], |
||||
|
|
||||
|
"post_load": None, |
||||
|
"pre_init_hook": None, |
||||
|
"post_init_hook": "post_init_hook", |
||||
|
"uninstall_hook": "uninstall_hook", |
||||
|
|
||||
|
"auto_install": False, |
||||
|
"installable": True, |
||||
|
|
||||
|
# "demo_title": "Email Addresses per Website", |
||||
|
# "demo_addons": [ |
||||
|
# ], |
||||
|
# "demo_addons_hidden": [ |
||||
|
# ], |
||||
|
# "demo_url": "DEMO-URL", |
||||
|
# "demo_summary": "Use single Backend to manage several Websites", |
||||
|
# "demo_images": [ |
||||
|
# "images/MAIN_IMAGE", |
||||
|
# ] |
||||
|
} |
@ -0,0 +1,4 @@ |
|||||
|
`1.0.0` |
||||
|
------- |
||||
|
|
||||
|
- **Init version** |
@ -0,0 +1,73 @@ |
|||||
|
=========================================== |
||||
|
Email Addresses and Templates per Website |
||||
|
=========================================== |
||||
|
|
||||
|
Installation |
||||
|
============ |
||||
|
|
||||
|
* `Install <https://odoo-development.readthedocs.io/en/latest/odoo/usage/install-module.html>`__ this module in a usual way |
||||
|
|
||||
|
Configuration |
||||
|
============= |
||||
|
|
||||
|
|
||||
|
Access to websites |
||||
|
------------------ |
||||
|
|
||||
|
* Go to menu ``[[ Settings ]] >> Users & Companies >> Users`` |
||||
|
* Select a user |
||||
|
* Grant access ``[x] Multi Websites for Backend`` |
||||
|
* Configure **Allowed Websites** |
||||
|
|
||||
|
User's email per website |
||||
|
------------------------ |
||||
|
|
||||
|
* Refresh page if you just granted your user access to websites |
||||
|
* Use top right-hand corner button with current website name to switch between websites |
||||
|
* Use top right-hand corner button with user name and avatar to open |
||||
|
Preference popup. When you edit **Email** field, it will be saved as a value |
||||
|
for current website. |
||||
|
|
||||
|
Email template per website |
||||
|
-------------------------- |
||||
|
|
||||
|
* Refresh page if you just granted your user access to websites |
||||
|
* `Activate Developer Mode <https://odoo-development.readthedocs.io/en/latest/odoo/usage/debug-mode.html>`__ |
||||
|
* Use top right-hand corner button with current website name to switch between websites |
||||
|
* Go to menu ``[[ Settings ]] >> Technical >> Email >> Templates`` |
||||
|
* When you edit template, following fields will be saved as a value for current website: |
||||
|
|
||||
|
* **Body** |
||||
|
* **Outgoing Mail Server** |
||||
|
* **Optional report to print and attach** |
||||
|
|
||||
|
* Additional variable ``website`` is available to configure rest fields (**Subject**, **From**, etc.) |
||||
|
|
||||
|
Note. If related record (e.g. ``sale.order``) has field ``company_id`` or ``website_id`` those values will be used instead of currently selected in Website / Company Switchers |
||||
|
|
||||
|
Alias domain per website |
||||
|
------------------------ |
||||
|
|
||||
|
Configure ``mail.catchall.domain`` per website. See Documentation of the module `Context-dependent values in System Parameters<https://apps.odoo.com/apps/modules/10.0/ir_config_parameter_multi_company/>`__. |
||||
|
|
||||
|
Outgoing mails servers per |
||||
|
-------------------------- |
||||
|
|
||||
|
If each domain has different Outgoing Mail Server you need following adjustments |
||||
|
|
||||
|
* Got to menu ``[[ Website ]] >> Configuration >> Websites`` |
||||
|
* In each Website specify field **Outgoing Mails** |
||||
|
|
||||
|
Properties |
||||
|
---------- |
||||
|
|
||||
|
To review properties by website use menu ``[[ Settings ]] >> Technical >> Parameters >> Company Properties``. See **How it works** in Documentation of module `Website Switcher in Backend<https://apps.odoo.com/apps/modules/10.0/web_website/>`__. |
||||
|
|
||||
|
Usage |
||||
|
===== |
||||
|
|
||||
|
When you work from backend, Email for current website is used. |
||||
|
|
||||
|
When a user do something on website (e.g. purchase products) and some mail is sent, then email address for that website will be used (mostly Administrator's email address). |
||||
|
|
||||
|
When email is sent, template's value like body, subject, etc. for current values are used. |
After Width: 750 | Height: 371 | Size: 285 KiB |
@ -0,0 +1,7 @@ |
|||||
|
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html). |
||||
|
from . import res_users |
||||
|
from . import ir_property |
||||
|
from . import mail_template |
||||
|
from . import mail_thread |
||||
|
from . import mail_message |
||||
|
from . import website |
@ -0,0 +1,20 @@ |
|||||
|
# Copyright 2018 Ivan Yelizariev <https://it-projects.info/team/yelizariev> |
||||
|
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html). |
||||
|
from odoo import models, api |
||||
|
|
||||
|
|
||||
|
class IrProperty(models.Model): |
||||
|
_inherit = 'ir.property' |
||||
|
|
||||
|
@api.multi |
||||
|
def write(self, vals): |
||||
|
res = super(IrProperty, self).write(vals) |
||||
|
field_object_list = [ |
||||
|
self.env.ref('base.field_res_users_email'), |
||||
|
self.env.ref('mail.field_mail_template_body_html'), |
||||
|
self.env.ref('mail.field_mail_template_mail_server_id'), |
||||
|
self.env.ref('mail.field_mail_template_report_template'), |
||||
|
] |
||||
|
for fobj in field_object_list: |
||||
|
self._update_db_value_website_dependent(fobj) |
||||
|
return res |
@ -0,0 +1,16 @@ |
|||||
|
# Copyright 2018 Ivan Yelizariev <https://it-projects.info/team/yelizariev> |
||||
|
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html). |
||||
|
from odoo import models, fields |
||||
|
|
||||
|
|
||||
|
class Message(models.Model): |
||||
|
_inherit = 'mail.message' |
||||
|
|
||||
|
def _default_mail_server_id(self): |
||||
|
website = self.env.context.get('website_id') |
||||
|
if not website: |
||||
|
return |
||||
|
website = self.env['website'].sudo().browse(website) |
||||
|
return website.mail_server_id.id |
||||
|
|
||||
|
mail_server_id = fields.Many2one(default=_default_mail_server_id) |
@ -0,0 +1,151 @@ |
|||||
|
# Copyright 2018 Ivan Yelizariev <https://it-projects.info/team/yelizariev> |
||||
|
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html). |
||||
|
import logging |
||||
|
from odoo import models, fields, api, tools, _ |
||||
|
from odoo.exceptions import UserError |
||||
|
from odoo.tools import pycompat |
||||
|
from odoo.addons.mail.models.mail_template import format_date, format_tz, format_amount |
||||
|
|
||||
|
_logger = logging.getLogger(__name__) |
||||
|
FIELDS = ['body_html', 'mail_server_id', 'report_template'] |
||||
|
|
||||
|
try: |
||||
|
from odoo.addons.mail.models.mail_template import mako_safe_template_env, mako_template_env |
||||
|
except ImportError: |
||||
|
_logger.warning("jinja2 not available, templating features will not work!") |
||||
|
|
||||
|
|
||||
|
class MailTemplate(models.Model): |
||||
|
|
||||
|
_inherit = ['mail.template', 'website_dependent.mixin'] |
||||
|
_name = 'mail.template' |
||||
|
|
||||
|
body_html = fields.Html(company_dependent=True, website_dependent=True) |
||||
|
mail_server_id = fields.Many2one(string='Outgoing Mail Server (Multi-Website)', company_dependent=True, website_dependent=True) |
||||
|
report_template = fields.Many2one(string='Optional report to print and attach (Multi-Website)', company_dependent=True, website_dependent=True) |
||||
|
|
||||
|
@api.multi |
||||
|
def generate_email(self, res_ids, fields=None): |
||||
|
"""Remove mail_server_id when not set to recompute in _default_mail_server_id in mail.message""" |
||||
|
multi_mode = True |
||||
|
if isinstance(res_ids, pycompat.integer_types): |
||||
|
multi_mode = False |
||||
|
res = super(MailTemplate, self).generate_email(res_ids, fields=fields) |
||||
|
if not multi_mode: |
||||
|
list_of_dict = {0: res} |
||||
|
else: |
||||
|
list_of_dict = res |
||||
|
|
||||
|
for _unused, data in list_of_dict.items(): |
||||
|
if 'mail_server_id' in data and not data.get('mail_server_id'): |
||||
|
del data['mail_server_id'] |
||||
|
|
||||
|
return res |
||||
|
|
||||
|
@api.model |
||||
|
def render_template(self, template_txt, model, res_ids, post_process=False): |
||||
|
"""Override to add website to context""" |
||||
|
multi_mode = True |
||||
|
if isinstance(res_ids, pycompat.integer_types): |
||||
|
multi_mode = False |
||||
|
res_ids = [res_ids] |
||||
|
|
||||
|
results = dict.fromkeys(res_ids, u"") |
||||
|
|
||||
|
# try to load the template |
||||
|
try: |
||||
|
mako_env = mako_safe_template_env if self.env.context.get('safe') else mako_template_env |
||||
|
template = mako_env.from_string(tools.ustr(template_txt)) |
||||
|
except Exception: |
||||
|
_logger.info("Failed to load template %r", template_txt, exc_info=True) |
||||
|
return multi_mode and results or results[res_ids[0]] |
||||
|
|
||||
|
# prepare template variables |
||||
|
records = self.env[model].browse(it for it in res_ids if it) # filter to avoid browsing [None] |
||||
|
res_to_rec = dict.fromkeys(res_ids, None) |
||||
|
for record in records: |
||||
|
res_to_rec[record.id] = record |
||||
|
|
||||
|
variables = { |
||||
|
'format_date': lambda date, format=False, context=self._context: format_date(self.env, date, format), |
||||
|
'format_tz': lambda dt, tz=False, format=False, context=self._context: format_tz(self.env, dt, tz, format), |
||||
|
'format_amount': lambda amount, currency, context=self._context: format_amount(self.env, amount, currency), |
||||
|
'user': self.env.user, |
||||
|
'ctx': self._context, # context kw would clash with mako internals |
||||
|
} |
||||
|
|
||||
|
# [NEW] Check website and company context |
||||
|
company = self.env['res.company'] # empty value |
||||
|
|
||||
|
company_id = self.env.context.get('force_company') |
||||
|
if company_id: |
||||
|
company = self.env['res.company'].sudo().browse(company_id) |
||||
|
|
||||
|
if self.env.context.get('website_id'): |
||||
|
website = self.env['website'].browse(self.env.context.get('website_id')) |
||||
|
else: |
||||
|
website = self.env.user.backend_website_id |
||||
|
|
||||
|
for res_id, record in res_to_rec.items(): |
||||
|
record_company = company |
||||
|
if not record_company: |
||||
|
if hasattr(record, 'company_id') and record.company_id: |
||||
|
record_company = record.company_id |
||||
|
|
||||
|
record_website = website |
||||
|
if hasattr(record, 'website_id') and record.website_id: |
||||
|
record_website = record.website_id |
||||
|
|
||||
|
if record_company and record_website \ |
||||
|
and record_website.company_id != company: |
||||
|
# company and website are incompatible, so keep only website |
||||
|
record_website = self.env['website'] # empty value |
||||
|
|
||||
|
record_context = dict(force_company=record_company.id, website_id=record_website.id) |
||||
|
variables['object'] = record.with_context(**record_context) |
||||
|
variables['website'] = record_website |
||||
|
|
||||
|
try: |
||||
|
render_result = template.render(variables) |
||||
|
except Exception: |
||||
|
_logger.info("Failed to render template %r using values %r" % (template, variables), exc_info=True) |
||||
|
raise UserError(_("Failed to render template %r using values %r") % (template, variables)) |
||||
|
if render_result == u"False": |
||||
|
render_result = u"" |
||||
|
|
||||
|
if post_process: |
||||
|
render_result = self.with_context(**record_context).render_post_process(render_result) |
||||
|
|
||||
|
results[res_id] = render_result |
||||
|
|
||||
|
return multi_mode and results or results[res_ids[0]] |
||||
|
|
||||
|
@api.model |
||||
|
def create(self, vals): |
||||
|
res = super(MailTemplate, self).create(vals) |
||||
|
# make value company independent |
||||
|
for f in FIELDS: |
||||
|
res._force_default(f, vals.get(f)) |
||||
|
return res |
||||
|
|
||||
|
@api.multi |
||||
|
def write(self, vals): |
||||
|
res = super(MailTemplate, self).write(vals) |
||||
|
|
||||
|
# TODO: will it work with OCA's partner_firstname module? |
||||
|
if 'name' in vals: |
||||
|
fields_to_update = FIELDS |
||||
|
else: |
||||
|
fields_to_update = [ |
||||
|
f for f in FIELDS |
||||
|
if f in vals |
||||
|
] |
||||
|
for f in fields_to_update: |
||||
|
self._update_properties_label(f) |
||||
|
|
||||
|
return res |
||||
|
|
||||
|
def _auto_init(self): |
||||
|
for f in FIELDS: |
||||
|
self._auto_init_website_dependent(f) |
||||
|
return super(MailTemplate, self)._auto_init() |
@ -0,0 +1,26 @@ |
|||||
|
# Copyright 2018 Ivan Yelizariev <https://it-projects.info/team/yelizariev> |
||||
|
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html). |
||||
|
from odoo import models, api, tools |
||||
|
|
||||
|
|
||||
|
class MailThread(models.AbstractModel): |
||||
|
_inherit = 'mail.thread' |
||||
|
|
||||
|
@api.model |
||||
|
def message_route_process(self, message, message_dict, routes): |
||||
|
rcpt_tos = ','.join([ |
||||
|
tools.decode_message_header(message, 'Delivered-To'), |
||||
|
tools.decode_message_header(message, 'To'), |
||||
|
tools.decode_message_header(message, 'Cc'), |
||||
|
tools.decode_message_header(message, 'Resent-To'), |
||||
|
tools.decode_message_header(message, 'Resent-Cc')]) |
||||
|
rcpt_tos_websiteparts = [e.split('@')[1].lower() for e in tools.email_split(rcpt_tos)] |
||||
|
website = self.env['website'].sudo().search([ |
||||
|
('domain', 'in', rcpt_tos_websiteparts) |
||||
|
]) |
||||
|
if website: |
||||
|
self = self.with_context(website_id=website[0].id) |
||||
|
|
||||
|
return super(MailThread, self).message_route_process( |
||||
|
message, message_dict, routes |
||||
|
) |
@ -0,0 +1,45 @@ |
|||||
|
# Copyright 2018 Ivan Yelizariev <https://it-projects.info/team/yelizariev> |
||||
|
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html). |
||||
|
import logging |
||||
|
from odoo import models, fields, api |
||||
|
|
||||
|
|
||||
|
_logger = logging.getLogger(__name__) |
||||
|
FIELD_NAME = 'email_multi_website' |
||||
|
FIELDS = ['signature'] |
||||
|
ALL_FIELDS = [FIELD_NAME] + FIELDS |
||||
|
|
||||
|
|
||||
|
class User(models.Model): |
||||
|
|
||||
|
_inherit = ['res.users', 'website_dependent.mixin'] |
||||
|
_name = 'res.users' |
||||
|
|
||||
|
signature = fields.Html(company_dependent=True, website_dependent=True) |
||||
|
|
||||
|
# extra field to detach email field from res.partner |
||||
|
email = fields.Char(related='email_multi_website', inherited=False) |
||||
|
email_multi_website = fields.Char(company_dependent=True, website_dependent=True) |
||||
|
|
||||
|
@api.model |
||||
|
def create(self, vals): |
||||
|
res = super(User, self).create(vals) |
||||
|
# make value company independent |
||||
|
res._force_default(FIELD_NAME, vals.get('email')) |
||||
|
for f in FIELDS: |
||||
|
res._force_default(f, vals.get(f)) |
||||
|
return res |
||||
|
|
||||
|
@api.multi |
||||
|
def write(self, vals): |
||||
|
res = super(User, self).write(vals) |
||||
|
# TODO: will it work with OCA's partner_firstname module? |
||||
|
if any(k in vals for k in ['name', 'email'] + FIELDS): |
||||
|
for f in ALL_FIELDS: |
||||
|
self._update_properties_label(f) |
||||
|
return res |
||||
|
|
||||
|
def _auto_init(self): |
||||
|
for f in FIELDS: |
||||
|
self._auto_init_website_dependent(f) |
||||
|
return super(User, self)._auto_init() |
@ -0,0 +1,10 @@ |
|||||
|
# Copyright 2017 Ivan Yelizariev <https://it-projects.info/team/yelizariev> |
||||
|
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html). |
||||
|
|
||||
|
from odoo import models, fields |
||||
|
|
||||
|
|
||||
|
class Website(models.Model): |
||||
|
_inherit = "website" |
||||
|
|
||||
|
mail_server_id = fields.Many2one('ir.mail_server', 'Outgoing Mails', help='Default outgoing mail server') |
Before Width: 100 | Height: 100 | Size: 2.1 KiB After Width: 100 | Height: 100 | Size: 2.1 KiB |
@ -0,0 +1,97 @@ |
|||||
|
<section class="oe_container"> |
||||
|
<div class="oe_row oe_spaced"> |
||||
|
<div class="oe_span12"> |
||||
|
<h2 class="oe_slogan" style="color:#875A7B;">Email Addresses and Templates per Website |
||||
|
</h2> |
||||
|
<h3 class="oe_slogan">Use single Backend to manage several Websites</h3> |
||||
|
</div> |
||||
|
</div> |
||||
|
</section> |
||||
|
|
||||
|
<section class="oe_container"> |
||||
|
<div class="oe_row oe_spaced"> |
||||
|
<div class="oe_span12"> |
||||
|
|
||||
|
<div class="alert alert-info oe_mt32" style="padding:0.3em 0.6em; font-size: 150%;"> |
||||
|
<i class="fa fa-hand-o-right"></i><b> Key features: </b> |
||||
|
<ul class="list-unstyled"> |
||||
|
|
||||
|
<li> |
||||
|
<i class="fa fa-check-square-o text-primary"></i> |
||||
|
Separate Mail Templates per website |
||||
|
</li> |
||||
|
|
||||
|
<li> |
||||
|
<i class="fa fa-check-square-o text-primary"></i> |
||||
|
<em>From</em> address in email has address for current Website |
||||
|
</li> |
||||
|
|
||||
|
<li> |
||||
|
<i class="fa fa-check-square-o text-primary"></i> |
||||
|
<em>Reply-To</em> address in email has domain of current Website |
||||
|
</li> |
||||
|
|
||||
|
<li> |
||||
|
<i class="fa fa-check-square-o text-primary"></i> |
||||
|
User's signature per Website |
||||
|
</li> |
||||
|
|
||||
|
</ul> |
||||
|
</div> |
||||
|
|
||||
|
</div> |
||||
|
</div> |
||||
|
</section> |
||||
|
|
||||
|
<section class="oe_container"> |
||||
|
<div class="oe_row oe_spaced"> |
||||
|
<div class="oe_span8"> |
||||
|
<h2>Need our service?</h2> |
||||
|
<p class="oe_mt32">Contact us by <a href="mailto:apps@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:apps@it-projects.info">apps@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> |
||||
|
<li><a href="https://m.me/itprojectsllc" target="_blank">https://m.me/itprojectsllc <i class="fa fa-facebook-square"></i></a></li> |
||||
|
<li>skype@it-projects.info <i class="fa fa-skype"></i></li> |
||||
|
</ul> |
||||
|
</div> |
||||
|
<div class="oe_span4"> |
||||
|
<div class="stamp" style="width:200px;"> |
||||
|
<div style="margin-top: 15px; |
||||
|
position: relative; |
||||
|
font-family:'Vollkorn', serif; |
||||
|
font-size: 16px; |
||||
|
line-height: 25px; |
||||
|
text-transform: uppercase; |
||||
|
font-weight: bold; |
||||
|
color: #75526b; |
||||
|
border: 3px dashed #75526b; |
||||
|
float: left; |
||||
|
padding: 4px 12px; |
||||
|
-webkit-transform: rotate(1deg); |
||||
|
-o-transform: rotate(1deg); |
||||
|
-moz-transform: rotate(1deg); |
||||
|
-ms-transform: rotate(1deg);"> |
||||
|
Tested on Odoo<br/>11.0 community |
||||
|
</div> |
||||
|
<!--<div style="margin-top: 15px; |
||||
|
position: relative; |
||||
|
font-family:'Vollkorn', serif; |
||||
|
font-size: 16px; |
||||
|
line-height: 25px; |
||||
|
text-transform: uppercase; |
||||
|
font-weight: bold; |
||||
|
color: #75526b; |
||||
|
border: 3px dashed #75526b; |
||||
|
float: left; |
||||
|
padding: 4px 12px; |
||||
|
-webkit-transform: rotate(1deg); |
||||
|
-o-transform: rotate(1deg); |
||||
|
-moz-transform: rotate(1deg); |
||||
|
-ms-transform: rotate(1deg);"> |
||||
|
Tested on Odoo<br/>11.0 enterprise |
||||
|
</div>--> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</section> |
@ -0,0 +1,4 @@ |
|||||
|
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html). |
||||
|
from . import test_send |
||||
|
from . import test_render |
||||
|
from . import test_fetch |
@ -0,0 +1,41 @@ |
|||||
|
# Copyright 2018 Ivan Yelizariev <https://it-projects.info/team/yelizariev> |
||||
|
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html). |
||||
|
from odoo.addons.mail.tests.common import TestMail |
||||
|
from odoo.tools import mute_logger |
||||
|
from odoo.addons.mail.tests.test_mail_gateway import MAIL_TEMPLATE |
||||
|
|
||||
|
|
||||
|
class TestFetch(TestMail): |
||||
|
at_install = True |
||||
|
post_install = True |
||||
|
|
||||
|
def setUp(self): |
||||
|
super(TestFetch, self).setUp() |
||||
|
self.website = self.env['website'].create({ |
||||
|
'name': 'Test Website', |
||||
|
'domain': 'example.com', |
||||
|
}) |
||||
|
self.company = self.env['res.company'].create({ |
||||
|
'name': 'New Test Website' |
||||
|
}) |
||||
|
self.website.company_id = self.company |
||||
|
|
||||
|
# copy-paste from mail.tests.test_mail_gateway |
||||
|
mail_test_model = self.env['ir.model']._get('mail.test') |
||||
|
# groups@.. will cause the creation of new mail.test |
||||
|
self.alias = self.env['mail.alias'].create({ |
||||
|
'alias_name': 'groups', |
||||
|
'alias_user_id': False, |
||||
|
'alias_model_id': mail_test_model.id, |
||||
|
'alias_contact': 'everyone'}) |
||||
|
|
||||
|
@mute_logger('odoo.addons.mail.models.mail_thread', 'odoo.models') |
||||
|
def test_fetch_multi_website(self): |
||||
|
""" Incoming email on an alias creating a new record + message_new + message details """ |
||||
|
new_groups = self.format_and_process(MAIL_TEMPLATE, subject='My Frogs', to='groups@example.com, other@gmail.com') |
||||
|
|
||||
|
# Test: one group created by mailgateway administrator |
||||
|
self.assertEqual(len(new_groups), 1, 'message_process: a new mail.test should have been created') |
||||
|
|
||||
|
self.assertEqual(new_groups.website_id, self.website, 'New record is created with wrong website') |
||||
|
self.assertEqual(new_groups.company_id, self.company, 'New record is created with wrong company') |
@ -0,0 +1,10 @@ |
|||||
|
# Copyright 2018 Ivan Yelizariev <https://it-projects.info/team/yelizariev> |
||||
|
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html). |
||||
|
from odoo import models, fields |
||||
|
|
||||
|
|
||||
|
class MailTest(models.Model): |
||||
|
_inherit = 'mail.test' |
||||
|
|
||||
|
company_id = fields.Many2one('res.company', default=lambda self: self.env['res.company']._company_default_get()) |
||||
|
website_id = fields.Many2one('website', default=lambda self: self.env['website'].browse(self.env.context.get('website_id'))) |