-
7.travis.yml
-
29mail_attachment_popup/README.rst
-
0mail_attachment_popup/__init__.py
-
29mail_attachment_popup/__openerp__.py
-
4mail_attachment_popup/doc/changelog.rst
-
16mail_attachment_popup/doc/index.rst
-
BINmail_attachment_popup/images/popup_image.png
-
BINmail_attachment_popup/static/description/attach_image.png
-
BINmail_attachment_popup/static/description/download.png
-
BINmail_attachment_popup/static/description/icon.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
-
4mail_delete_odoo_footer/README.rst
-
0mail_delete_odoo_footer/__init__.py
-
14mail_delete_odoo_footer/__openerp__.py
-
BINmail_delete_odoo_footer/static/description/icon.png
-
6mail_fix_empty_body/README.rst
-
2mail_fix_empty_body/__init__.py
-
16mail_fix_empty_body/__openerp__.py
-
12mail_fix_empty_body/models.py
-
BINmail_fix_empty_body/static/description/icon.png
-
65mail_fix_empty_body/static/description/index.html
-
BINmail_fix_empty_body/static/description/receive-false.png
-
BINmail_fix_empty_body/static/description/receive-ok.png
-
BINmail_fix_empty_body/static/description/send.png
-
2mail_fix_header_from/__init__.py
-
18mail_fix_header_from/__openerp__.py
-
5mail_fix_header_from/models.py
-
BINmail_fix_header_from/static/description/icon.png
-
2mail_outgoing/__init__.py
-
22mail_outgoing/__openerp__.py
-
25mail_outgoing/mail_outgoing_models.py
-
34mail_outgoing/mail_outgoing_views.xml
-
3mail_outgoing/security/ir.model.access.csv
-
33mail_outgoing/security/mail_outgoing.xml
-
BINmail_outgoing/static/description/icon.png
-
4mail_partner_lang/README.rst
-
2mail_partner_lang/__init__.py
-
14mail_partner_lang/__openerp__.py
-
88mail_partner_lang/models.py
-
BINmail_partner_lang/static/description/icon.png
-
2mail_todo_custom/README.rst
-
0mail_todo_custom/__init__.py
-
14mail_todo_custom/__openerp__.py
-
25mail_todo_custom/mail_todo_custom.xml
-
44mail_todo_custom/static/src/js/mail_todo_custom.js
-
1mailgun/__openerp__.py
-
2mass_mailing_extra/__init__.py
-
23mass_mailing_extra/__openerp__.py
-
41mass_mailing_extra/models.py
-
BINmass_mailing_extra/static/description/icon.png
-
38mass_mailing_extra/views.xml
-
1res_partner_strip_email/README.rst
-
2res_partner_strip_email/__init__.py
-
22res_partner_strip_email/__openerp__.py
-
29res_partner_strip_email/models.py
-
BINres_partner_strip_email/static/description/icon.png
@ -1,29 +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>`_ |
|||
|
|||
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,29 +0,0 @@ |
|||
# -*- coding: utf-8 -*- |
|||
{ |
|||
"name": """Popup Attachments""", |
|||
"summary": """Open attached mail images in popup""", |
|||
"category": "Extra Tools", |
|||
"version": "1.0.0", |
|||
"images": ['images/popup_image.png'], |
|||
|
|||
"author": "IT-Projects LLC, Dinar Gabbasov", |
|||
"support": "apps@it-projects.info", |
|||
'website': "https://twitter.com/gabbasov_dinar", |
|||
"license": "GPL-3", |
|||
"price": "50.0", |
|||
"currency": "EUR", |
|||
|
|||
"depends": [ |
|||
"mail", |
|||
], |
|||
"external_dependencies": {"python": [], "bin": []}, |
|||
"data": [ |
|||
"views/mail_attachment_popup_template.xml", |
|||
], |
|||
"qweb": [ |
|||
"static/src/xml/mail_attachment_popup.xml", |
|||
], |
|||
|
|||
"installable": False, |
|||
'auto_install': False, |
|||
} |
@ -1,4 +0,0 @@ |
|||
`1.0.0` |
|||
------- |
|||
|
|||
- Init version |
@ -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 |
Before Width: 749 | Height: 371 | Size: 128 KiB |
Before Width: 361 | Height: 382 | Size: 63 KiB |
Before Width: 361 | Height: 381 | Size: 131 KiB |
Before Width: 100 | Height: 100 | Size: 2.1 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: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> |
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 +0,0 @@ |
|||
Delete Odoo footer in email |
|||
=========================== |
|||
|
|||
Tested on 8.0 ab7b5d7732a7c222a0aea45bd173742acd47242d |
@ -1,14 +0,0 @@ |
|||
# -*- coding: utf-8 -*- |
|||
{ |
|||
'name': 'Delete Odoo footer in email (TODO)', |
|||
'version': '1.0.0', |
|||
'author': 'IT-Projects LLC, Ivan Yelizariev', |
|||
'license': 'LGPL-3', |
|||
"category": "Discuss", |
|||
"support": "apps@it-projects.info", |
|||
'website': 'https://yelizariev.github.io', |
|||
'depends': [], |
|||
'data': [ |
|||
], |
|||
'installable': False |
|||
} |
Before Width: 100 | Height: 100 | Size: 2.1 KiB |
@ -1,6 +0,0 @@ |
|||
Fix "False" in empty email body |
|||
=============================== |
|||
|
|||
Description: https://apps.odoo.com/apps/modules/8.0/mail_fix_empty_body/ |
|||
|
|||
Tested on Odoo 8.0 ab7b5d7732a7c222a0aea45bd173742acd47242d |
@ -1,2 +0,0 @@ |
|||
# -*- coding: utf-8 -*- |
|||
from . import models |
@ -1,16 +0,0 @@ |
|||
# -*- coding: utf-8 -*- |
|||
{ |
|||
'name': 'Fix "False" in empty email body', |
|||
'version': '1.0.0', |
|||
'author': 'IT-Projects LLC, Ivan Yelizariev', |
|||
'license': 'LGPL-3', |
|||
"category": "Discuss", |
|||
"support": "apps@it-projects.info", |
|||
'website': 'https://twitter.com/yelizariev', |
|||
'price': 9.00, |
|||
'currency': 'EUR', |
|||
'depends': ['mail'], |
|||
'data': [ |
|||
], |
|||
'installable': False |
|||
} |
@ -1,12 +0,0 @@ |
|||
# -*- coding: utf-8 -*- |
|||
from openerp import models |
|||
|
|||
|
|||
class MailComposeMessage(models.TransientModel): |
|||
_inherit = 'mail.compose.message' |
|||
|
|||
def get_mail_values(self, cr, uid, wizard, res_ids, context=None): |
|||
res = super(MailComposeMessage, self).get_mail_values(cr, uid, wizard, res_ids, context) |
|||
for id, d in res.iteritems(): |
|||
d['body'] = d.get('body') or '' |
|||
return res |
Before Width: 100 | Height: 100 | Size: 2.1 KiB |
@ -1,65 +0,0 @@ |
|||
<section class="oe_container"> |
|||
<div class="oe_row oe_spaced"> |
|||
<div class="oe_span12"> |
|||
<h2 class="oe_slogan">Fix "False" in empty email body</h2> |
|||
<h3 class="oe_slogan">Feel free to send emails without body</h3> |
|||
</div> |
|||
|
|||
<div class="oe_span8"> |
|||
<p class="oe_mt32"> |
|||
Some time you need to send email with empty body. <br/>E.g. to send some file to partner. |
|||
</p> |
|||
</div> |
|||
<div class="oe_span8 oe_right"> |
|||
<div class="oe_demo oe_picture oe_screenshot"> |
|||
<img src="send.png?1"/> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</section> |
|||
|
|||
<section class="oe_container oe_dark"> |
|||
<div class="oe_row oe_spaced"> |
|||
<div class="oe_span6"> |
|||
<div class="oe_demo oe_picture oe_screenshot"> |
|||
<img src="receive-false.png"/> |
|||
</div> |
|||
</div> |
|||
|
|||
<div class="oe_span6"> |
|||
<p class="oe_mt32"> |
|||
There is a bug in odoo -- it sends "False" if email body if empty. |
|||
</p> |
|||
</div> |
|||
</div> |
|||
</section> |
|||
|
|||
|
|||
<section class="oe_container"> |
|||
<div class="oe_row oe_spaced"> |
|||
<div class="oe_span6"> |
|||
<p class="oe_mt32"> |
|||
This module just fix the issue. |
|||
</p> |
|||
</div> |
|||
<div class="oe_span6"> |
|||
<div class="oe_demo oe_picture oe_screenshot"> |
|||
<img src="receive-ok.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: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> |
Before Width: 366 | Height: 276 | Size: 18 KiB |
Before Width: 350 | Height: 280 | Size: 16 KiB |
Before Width: 581 | Height: 400 | Size: 31 KiB |
@ -1,2 +0,0 @@ |
|||
# -*- coding: utf-8 -*- |
|||
from . import models |
@ -1,18 +0,0 @@ |
|||
# -*- coding: utf-8 -*- |
|||
{ |
|||
"name": "Fix non-ascii header 'from' (OBSOLETE)", |
|||
"version": "0.3", |
|||
"author": "IT-Projects LLC, Ivan Yelizariev", |
|||
'license': 'LGPL-3', |
|||
"category": "Discuss", |
|||
"support": "apps@it-projects.info", |
|||
"website": "https://yelizariev.github.io", |
|||
"description": """ |
|||
Obsolete in odoo 8.0 since Sep 10, 2014 https://github.com/odoo/odoo/commit/f2cf6ced17d3477b8858e3a8f955a42cc8a629ff . You can install this module, if you use older version. |
|||
""", |
|||
"depends": ["base"], |
|||
# "init_xml" : [], |
|||
# "update_xml" : [], |
|||
# "active": True, |
|||
'installable': False |
|||
} |
@ -1,5 +0,0 @@ |
|||
# -*- coding: utf-8 -*- |
|||
import re |
|||
from openerp.addons.base.ir import ir_mail_server |
|||
|
|||
ir_mail_server.name_with_email_pattern = re.compile(r'([^<@>]+)\s*<([^ ,<@]+@[^> ,]+)>') |
Before Width: 100 | Height: 100 | Size: 2.1 KiB |
@ -1,2 +0,0 @@ |
|||
# -*- coding: utf-8 -*- |
|||
from . import mail_outgoing_models |
@ -1,22 +0,0 @@ |
|||
# -*- coding: utf-8 -*- |
|||
{ |
|||
'name': 'Outgoing mails menu', |
|||
'version': '1.0.0', |
|||
'author': 'IT-Projects LLC, Ivan Yelizariev', |
|||
'license': 'LGPL-3', |
|||
"category": "Discuss", |
|||
"support": "apps@it-projects.info", |
|||
'website': 'https://yelizariev.github.io', |
|||
'description': """ |
|||
Allows to check outgoing mails, i.e. failed or delayed. |
|||
|
|||
Tested on Odoo 8.0 ab7b5d7732a7c222a0aea45bd173742acd47242d |
|||
""", |
|||
'depends': ['mail'], |
|||
'data': [ |
|||
'security/mail_outgoing.xml', |
|||
'security/ir.model.access.csv', |
|||
'mail_outgoing_views.xml', |
|||
], |
|||
'installable': False |
|||
} |
@ -1,25 +0,0 @@ |
|||
# -*- coding: utf-8 -*- |
|||
from openerp.osv import osv |
|||
|
|||
|
|||
class MailMessage(osv.Model): |
|||
_inherit = 'mail.message' |
|||
|
|||
def check_access_rule(self, cr, uid, ids, operation, context=None): |
|||
group_all_emails = self.pool.get('ir.model.data').xmlid_to_object(cr, uid, 'mail_outgoing.group_all_emails', context=context) |
|||
|
|||
user = self.pool['res.users'].browse(cr, uid, uid, context) |
|||
user_groups = set(user.groups_id) |
|||
if user_groups.issuperset(group_all_emails): |
|||
return |
|||
|
|||
return super(MailMessage, self).check_access_rule(cr, uid, ids, operation, context) |
|||
|
|||
|
|||
class MailMail(osv.Model): |
|||
_name = 'mail.mail' |
|||
_inherit = ['mail.mail', 'ir.needaction_mixin'] |
|||
_needaction = True |
|||
|
|||
def _needaction_domain_get(self, cr, uid, context=None): |
|||
return [('state', 'in', ['outgoing', 'exception'])] |
@ -1,34 +0,0 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<openerp> |
|||
<data> |
|||
|
|||
<record id="action_mail_outgoing" model="ir.actions.act_window"> |
|||
<field name="name">Outgoing</field> |
|||
<field name="res_model">mail.mail</field> |
|||
<field name="view_type">form</field> |
|||
<field name="view_mode">tree,form</field> |
|||
<field name="context">{}</field> |
|||
<field name="search_view_id" ref="mail.view_mail_search"/> |
|||
<field name="help" type="html"> |
|||
<p> |
|||
Failed or delayed emails will be shown here. You will be able to retry failed emails and send delayed emails manually. |
|||
</p> |
|||
</field> |
|||
</record> |
|||
|
|||
<menuitem name="Outgoing" id="menu_mail_outgoing" parent="mail.mail_feeds" action="action_mail_outgoing" sequence="20"/> |
|||
|
|||
<!-- After installation of the module, open the related menu --> |
|||
<record id="action_mail_outgoing_menu" model="ir.actions.client"> |
|||
<field name="name">Open Outgoing Menu</field> |
|||
<field name="tag">reload</field> |
|||
<field name="params" eval="{'menu_id': ref('mail_outgoing.menu_mail_outgoing')}"/> |
|||
</record> |
|||
<record id="base.open_menu" model="ir.actions.todo"> |
|||
<field name="action_id" ref="action_mail_outgoing_menu"/> |
|||
<field name="state">open</field> |
|||
</record> |
|||
|
|||
|
|||
</data> |
|||
</openerp> |
@ -1,3 +0,0 @@ |
|||
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink |
|||
access_mail_mail_system,mail.mail.system,model_mail_mail,mail_outgoing.group_all_emails,1,1,1,1 |
|||
|
@ -1,33 +0,0 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<openerp> |
|||
<data> |
|||
<record model="res.groups" id="group_all_emails"> |
|||
<field name="name">all_emails</field> |
|||
<field name="comment">Gets access to all emails. For example to check outgoing emails.</field> |
|||
</record> |
|||
|
|||
<record model="ir.rule" id="rule_mail_mail_user"> |
|||
<field name="name">mail.mail: user</field> |
|||
<field name="model_id" ref="mail.model_mail_mail"/> |
|||
<field name="domain_force">[('author_id', '=', user.partner_id.id)]</field> |
|||
<field name="groups" eval="[(4, ref('base.group_user'))]"/> |
|||
<field name="perm_read" eval="True"/> |
|||
<field name="perm_write" eval="True"/> |
|||
<field name="perm_create" eval="True"/> |
|||
<field name="perm_unlink" eval="False"/> |
|||
<field name="global" eval="False"/> |
|||
</record> |
|||
|
|||
<record model="ir.rule" id="rule_mail_mail_system"> |
|||
<field name="name">mail.mail: system</field> |
|||
<field name="model_id" ref="mail.model_mail_mail"/> |
|||
<field name="domain_force">[(1, '=', 1)]</field> |
|||
<field name="groups" eval="[(4, ref('mail_outgoing.group_all_emails'))]"/> |
|||
<field name="perm_read" eval="True"/> |
|||
<field name="perm_write" eval="True"/> |
|||
<field name="perm_create" eval="True"/> |
|||
<field name="perm_unlink" eval="True"/> |
|||
<field name="global" eval="False"/> |
|||
</record> |
|||
</data> |
|||
</openerp> |
Before Width: 100 | Height: 100 | Size: 2.1 KiB |
@ -1,4 +0,0 @@ |
|||
Use partner language in mail |
|||
============================ |
|||
|
|||
FIXME: there is issue with frozen dict in new odoo. |
@ -1,2 +0,0 @@ |
|||
# -*- coding: utf-8 -*- |
|||
from . import models |
@ -1,14 +0,0 @@ |
|||
# -*- coding: utf-8 -*- |
|||
{ |
|||
'name': 'Use partner language in mail', |
|||
'version': '1.0.0', |
|||
'author': 'IT-Projects LLC, Ivan Yelizariev', |
|||
'license': 'LGPL-3', |
|||
"category": "Discuss", |
|||
"support": "apps@it-projects.info", |
|||
'website': 'https://yelizariev.github.io', |
|||
|
|||
'depends': ['mail'], |
|||
'data': [], |
|||
'installable': False, |
|||
} |
@ -1,88 +0,0 @@ |
|||
# -*- coding: utf-8 -*- |
|||
from openerp.osv import osv |
|||
|
|||
|
|||
class MailThread(osv.Model): |
|||
_inherit = "mail.thread" |
|||
|
|||
def message_track(self, cr, uid, ids, tracked_fields, initial_values, context={}): |
|||
|
|||
def convert_for_display(value, col_info): |
|||
if not value and col_info['type'] == 'boolean': |
|||
return 'False' |
|||
if not value: |
|||
return '' |
|||
if col_info['type'] == 'many2one': |
|||
return value.name_get()[0][1] |
|||
if col_info['type'] == 'selection': |
|||
return dict(col_info['selection'])[value] |
|||
return value |
|||
|
|||
def format_message(message_description, tracked_values): |
|||
message = '' |
|||
if message_description: |
|||
message = '<span>%s</span>' % message_description |
|||
for name, change in tracked_values.items(): |
|||
message += '<div> • <b>%s</b>: ' % change.get('col_info') |
|||
if change.get('old_value'): |
|||
message += '%s → ' % change.get('old_value') |
|||
message += '%s</div>' % change.get('new_value') |
|||
return message |
|||
|
|||
if not tracked_fields: |
|||
return True |
|||
|
|||
update_fields = [f for f in tracked_fields] |
|||
|
|||
for browse_record in self.browse(cr, uid, ids, context=context): |
|||
p = getattr(browse_record, 'partner_id', None) |
|||
if p: |
|||
browse_record._context.update({'lang': p.lang}) |
|||
|
|||
initial = initial_values[browse_record.id] |
|||
changes = set() |
|||
tracked_values = {} |
|||
|
|||
# update translation |
|||
tracked_fields = self._get_tracked_fields(cr, uid, update_fields, browse_record._context) |
|||
|
|||
# generate tracked_values data structure: {'col_name': {col_info, new_value, old_value}} |
|||
for col_name, col_info in tracked_fields.items(): |
|||
initial_value = initial[col_name] |
|||
record_value = getattr(browse_record, col_name) |
|||
|
|||
if record_value == initial_value and getattr(self._all_columns[col_name].column, 'track_visibility', None) == 'always': |
|||
tracked_values[col_name] = dict(col_info=col_info['string'], |
|||
new_value=convert_for_display(record_value, col_info)) |
|||
elif record_value != initial_value and (record_value or initial_value): # because browse null != False |
|||
if getattr(self._all_columns[col_name].column, 'track_visibility', None) in ['always', 'onchange']: |
|||
tracked_values[col_name] = dict(col_info=col_info['string'], |
|||
old_value=convert_for_display(initial_value, col_info), |
|||
new_value=convert_for_display(record_value, col_info)) |
|||
if col_name in tracked_fields: |
|||
changes.add(col_name) |
|||
if not changes: |
|||
continue |
|||
|
|||
# find subtypes and post messages or log if no subtype found |
|||
subtypes = [] |
|||
for field, track_info in self._track.items(): |
|||
if field not in changes: |
|||
continue |
|||
for subtype, method in track_info.items(): |
|||
if method(self, cr, uid, browse_record, context): |
|||
subtypes.append(subtype) |
|||
|
|||
posted = False |
|||
for subtype in subtypes: |
|||
subtype_rec = self.pool.get('ir.model.data').xmlid_to_object(cr, uid, subtype, context=context) |
|||
if not (subtype_rec and subtype_rec.exists()): |
|||
_logger.debug('subtype %s not found' % subtype) |
|||
continue |
|||
message = format_message(subtype_rec.description if subtype_rec.description else subtype_rec.name, tracked_values) |
|||
self.message_post(cr, uid, browse_record.id, body=message, subtype=subtype, context=context) |
|||
posted = True |
|||
if not posted: |
|||
message = format_message('', tracked_values) |
|||
self.message_post(cr, uid, browse_record.id, body=message, context=context) |
|||
return True |
Before Width: 100 | Height: 100 | Size: 2.1 KiB |
@ -1,2 +0,0 @@ |
|||
Mark unstarred email as read, remove filter in 'To-do' folder |
|||
============================================================= |
@ -1,14 +0,0 @@ |
|||
# -*- coding: utf-8 -*- |
|||
{ |
|||
'name': "Mark unstarred email as read, remove filter in 'To-do' folder", |
|||
'version': '1.0', |
|||
'author': 'IT-Projects LLC', |
|||
'license': 'LGPL-3', |
|||
"support": "apps@it-projects.info", |
|||
'website': "https://yelizariev.github.io", |
|||
"category": "Discuss", |
|||
'depends': ['mail'], |
|||
'data': ['mail_todo_custom.xml'], |
|||
'demo': [], |
|||
'installable': False, |
|||
} |
@ -1,25 +0,0 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<openerp> |
|||
<data> |
|||
|
|||
<template id="assets_backend_inherited_mail_todo_custom" name="Mail todo custom" inherit_id="web.assets_backend"> |
|||
<xpath expr="." position="inside"> |
|||
<script type="text/javascript" src="/mail_todo_custom/static/src/js/mail_todo_custom.js"></script> |
|||
</xpath> |
|||
</template> |
|||
|
|||
<record id="mail.action_mail_star_feeds" model="ir.actions.client"> |
|||
<field name="context"> |
|||
{ |
|||
'default_model': 'res.users', |
|||
'default_res_id': uid, |
|||
'thread_model': 'res.partner', |
|||
'search_default_message_unread': False, |
|||
'view_todo': True |
|||
} |
|||
</field> |
|||
</record> |
|||
|
|||
|
|||
</data> |
|||
</openerp> |
@ -1,44 +0,0 @@ |
|||
openerp.mail_todo_custom = function(session) { |
|||
|
|||
var mail = session.mail; |
|||
|
|||
mail.ThreadMessage.include({ |
|||
|
|||
on_star: function (event) { |
|||
event.stopPropagation(); |
|||
var self=this; |
|||
var button = self.$('.oe_star:first'); |
|||
|
|||
this.ds_message.call('set_message_starred', [[self.id], !self.is_favorite, true]) |
|||
.then(function (star) { |
|||
self.is_favorite=star; |
|||
if (self.is_favorite) { |
|||
button.addClass('oe_starred'); |
|||
} else { |
|||
button.removeClass('oe_starred'); |
|||
} |
|||
|
|||
if (self.options.view_inbox && self.is_favorite) { |
|||
self.on_message_read_unread(true); |
|||
} |
|||
else { |
|||
self.check_for_rerender(); |
|||
} |
|||
if (self.options.view_todo && !self.is_favorite) { |
|||
self.on_message_read_unread(true); |
|||
} |
|||
}); |
|||
return false; |
|||
}, |
|||
|
|||
}); |
|||
|
|||
mail.Widget.include({ |
|||
|
|||
init: function (parent, action) { |
|||
this._super(parent, action); |
|||
this.action.params.view_todo = this.action.context.view_todo || false; |
|||
}, |
|||
|
|||
}); |
|||
}; |
@ -1,2 +0,0 @@ |
|||
# -*- coding: utf-8 -*- |
|||
from . import models |
@ -1,23 +0,0 @@ |
|||
# -*- coding: utf-8 -*- |
|||
{ |
|||
'name': 'Improvements for mass mailing', |
|||
'version': '1.0.0', |
|||
'author': 'IT-Projects LLC, Ivan Yelizariev', |
|||
'license': 'LGPL-3', |
|||
"category": "Discuss", |
|||
"support": "apps@it-projects.info", |
|||
'website': 'https://yelizariev.github.io', |
|||
'description': """ |
|||
Modules adds: |
|||
|
|||
* partners info in mail.mail.statistics tree |
|||
* partners info in mail.mail.statistics form |
|||
|
|||
Tested on 8.0 f8d5a6727d3e8d428d9bef93da7ba6b11f344284 |
|||
""", |
|||
'depends': ['mass_mailing'], |
|||
'data': [ |
|||
'views.xml', |
|||
], |
|||
'installable': False |
|||
} |
@ -1,41 +0,0 @@ |
|||
# -*- coding: utf-8 -*- |
|||
from openerp import api, models, fields |
|||
|
|||
|
|||
class MailMailStats(models.Model): |
|||
|
|||
_inherit = 'mail.mail.statistics' |
|||
|
|||
partner_ids = fields.Many2many('res.partner', related='mail_mail_id.recipient_ids', string='Partners (Mail)') |
|||
|
|||
@api.multi |
|||
def _get_partner_id(self): |
|||
for r in self: |
|||
r._get_partner_id_one() |
|||
|
|||
@api.multi |
|||
def _get_partner_id_one(self): |
|||
self.ensure_one() |
|||
if self.model == 'res.partner': |
|||
self.partner_id = self.res_id |
|||
else: |
|||
self.partner_id = None |
|||
|
|||
partner_id = fields.Many2one('res.partner', compute=_get_partner_id, string='Partner (Document ID)') |
|||
|
|||
@api.multi |
|||
def _get_partners(self): |
|||
for r in self: |
|||
r._get_partners_one() |
|||
|
|||
@api.multi |
|||
def _get_partners_one(self): |
|||
self.ensure_one() |
|||
res = {} |
|||
for p in self.partner_ids: |
|||
res[p.id] = p |
|||
if self.partner_id and self.partner_id.id not in res: |
|||
res[self.partner_id.id] = self.partner_id |
|||
self.partners = ', '.join([('%s <%s>' % (p.name, p.email)) for id, p in res.items()]) |
|||
|
|||
partners = fields.Char('Partners', compute=_get_partners) |
Before Width: 100 | Height: 100 | Size: 2.1 KiB |
@ -1,38 +0,0 @@ |
|||
<?xml version="1.0"?> |
|||
<openerp> |
|||
<data> |
|||
|
|||
<record model="ir.ui.view" id="view_mail_mail_statistics_form"> |
|||
<field name="name">mail.mail.statistics.form</field> |
|||
<field name="model">mail.mail.statistics</field> |
|||
<field name="inherit_id" ref="mass_mailing.view_mail_mail_statistics_form"/> |
|||
<field name="arch" type="xml"> |
|||
<xpath expr="//form" position="inside"> |
|||
<notebook> |
|||
<page string="Partners"> |
|||
<group> |
|||
<label for="partners" string="Partners (summary)"/> |
|||
<field name="partners" readonly="1" nolabel="1"/> |
|||
<field name="partner_id" readonly="1"/> |
|||
</group> |
|||
<label for="partner_ids"/> |
|||
<field name="partner_ids" readonly="1"/> |
|||
</page> |
|||
</notebook> |
|||
</xpath> |
|||
</field> |
|||
</record> |
|||
|
|||
<record model="ir.ui.view" id="view_mail_mail_statistics_tree"> |
|||
<field name="name">mail.mail.statistics.tree</field> |
|||
<field name="model">mail.mail.statistics</field> |
|||
<field name="inherit_id" ref="mass_mailing.view_mail_mail_statistics_tree"/> |
|||
<field name="arch" type="xml"> |
|||
<xpath expr="//field[@name='mail_mail_id_int']" position="before"> |
|||
<field name="partners"/> |
|||
</xpath> |
|||
</field> |
|||
</record> |
|||
|
|||
</data> |
|||
</openerp> |
@ -1 +0,0 @@ |
|||
Trim email field in partner form. |
@ -1,2 +0,0 @@ |
|||
# -*- coding: utf-8 -*- |
|||
from . import models |
@ -1,22 +0,0 @@ |
|||
# -*- coding: utf-8 -*- |
|||
{ |
|||
'name': "Trim partner's email", |
|||
'summary': "", |
|||
'author': "IT-Projects LLC, Ivan Yelizariev", |
|||
'license': 'LGPL-3', |
|||
"support": "apps@it-projects.info", |
|||
'website': "https://yelizariev.github.io", |
|||
|
|||
# Categories can be used to filter modules in modules listing |
|||
# Check https://github.com/odoo/odoo/blob/master/openerp/addons/base/module/module_data.xml |
|||
# for the full list |
|||
"category": "Discuss", |
|||
'version': '1.0.0', |
|||
|
|||
# any module necessary for this one to work correctly |
|||
'depends': ['base'], |
|||
|
|||
# always loaded |
|||
'data': [], |
|||
'installable': False, |
|||
} |
@ -1,29 +0,0 @@ |
|||
# -*- coding: utf-8 -*- |
|||
|
|||
from openerp import api |
|||
from openerp import models |
|||
|
|||
|
|||
class ResPartnerStripEmail(models.Model): |
|||
_inherit = 'res.partner' |
|||
|
|||
@api.multi |
|||
def write(self, vals): |
|||
for r in self: |
|||
r.write_one(vals) |
|||
|
|||
@api.multi |
|||
def write_one(self, vals): |
|||
self.ensure_one() |
|||
vals = self._check_email_field(vals) |
|||
return super(ResPartnerStripEmail, self).write(vals) |
|||
|
|||
@api.model |
|||
def create(self, vals): |
|||
vals = self._check_email_field(vals) |
|||
return super(ResPartnerStripEmail, self).create(vals) |
|||
|
|||
def _check_email_field(self, vals): |
|||
if vals.get('email'): |
|||
vals['email'] = vals['email'].strip() |
|||
return vals |
Before Width: 100 | Height: 100 | Size: 3.0 KiB |