Ivan Yelizariev
5 years ago
No known key found for this signature in database
GPG Key ID: 93F14FB6A8B57057
107 changed files with 2172 additions and 1621 deletions
-
6.DINAR/image/README.md
-
1.DINAR/image/src/addons.yaml
-
13.github/workflows/main.yml
-
2.isort.cfg
-
19.travis.yml
-
24mail_all/__manifest__.py
-
77mail_all/static/src/js/mail_all.js
-
32mail_all/static/src/js/test_mail_all.js
-
11mail_all/static/src/xml/menu.xml
-
17mail_all/tests/test_js.py
-
22mail_all/views/templates.xml
-
23mail_archives/__manifest__.py
-
159mail_archives/static/src/js/archives.js
-
12mail_archives/static/src/xml/menu.xml
-
1mail_archives/tests/__init__.py
-
17mail_archives/tests/test_js.py
-
20mail_archives/views/templates.xml
-
1mail_base/__init__.py
-
18mail_base/__manifest__.py
-
4mail_base/controllers/main.py
-
21mail_base/models.py
-
1mail_base/tests/__init__.py
-
7mail_base/tests/test_default.py
-
12mail_base/views/templates.xml
-
26mail_check_immediately/__manifest__.py
-
49mail_check_immediately/models.py
-
52mail_check_immediately/static/src/js/main.js
-
14mail_check_immediately/static/src/xml/main.xml
-
11mail_check_immediately/views.xml
-
4mail_fix_553/__manifest__.py
-
2mail_fix_553/data.xml
-
148mail_fix_553/mail_fix_553.py
-
33mail_move_message/__manifest__.py
-
5mail_move_message/controllers/main.py
-
3mail_move_message/data/mail_move_message_data.xml
-
524mail_move_message/mail_move_message_models.py
-
135mail_move_message/mail_move_message_views.xml
-
5mail_move_message/static/src/css/mail_move_message.css
-
149mail_move_message/static/src/js/mail_move_message.js
-
11mail_move_message/static/src/xml/mail_move_message_main.xml
-
1mail_move_message/tests/__init__.py
-
13mail_move_message/tests/test_mail_move.py
-
18mail_multi_website/__init__.py
-
15mail_multi_website/__manifest__.py
-
12mail_multi_website/models/ir_property.py
-
8mail_multi_website/models/mail_message.py
-
112mail_multi_website/models/mail_template.py
-
29mail_multi_website/models/mail_thread.py
-
18mail_multi_website/models/res_users.py
-
6mail_multi_website/models/website.py
-
53mail_multi_website/tests/test_fetch.py
-
16mail_multi_website/tests/test_mail_model.py
-
147mail_multi_website/tests/test_render.py
-
49mail_multi_website/tests/test_send.py
-
6mail_multi_website/views/website_views.xml
-
12mail_multi_website/wizard/mail_compose_message.py
-
21mail_private/__manifest__.py
-
15mail_private/full_composer_wizard.xml
-
78mail_private/models.py
-
485mail_private/static/src/js/mail_private.js
-
67mail_private/static/src/js/test_private.js
-
14mail_private/static/src/xml/mail_private.xml
-
19mail_private/template.xml
-
16mail_private/tests/test_js.py
-
22mail_recovery/__manifest__.py
-
13mail_recovery/data.xml
-
14mail_recovery/static/src/js/mail_recovery.js
-
14mail_reply/__manifest__.py
-
76mail_reply/static/src/js/mail_reply.js
-
14mail_reply/static/src/xml/reply_button.xml
-
15mail_reply/templates.xml
-
1mail_reply/tests/__init__.py
-
7mail_reply/tests/test_default.py
-
23mail_sent/__manifest__.py
-
38mail_sent/models.py
-
155mail_sent/static/src/js/sent.js
-
15mail_sent/static/src/xml/menu.xml
-
1mail_sent/tests/__init__.py
-
17mail_sent/tests/test_js.py
-
14mail_sent/views/templates.xml
-
16mail_to/__manifest__.py
-
15mail_to/static/src/xml/recipient.xml
-
12mail_to/templates.xml
-
47mail_to/tests/test_default.py
-
23mailgun/__manifest__.py
-
16mailgun/controllers/main.py
-
6mailgun/data/ir_cron_data.xml
-
21mailgun/models/ir_config_parameter.py
-
19mailgun/models/mail_thread.py
-
22res_partner_company_messages/__manifest__.py
-
16res_partner_company_messages/models.py
-
2res_partner_company_messages/views.xml
-
14res_partner_mails_count/__manifest__.py
-
15res_partner_mails_count/models.py
-
44res_partner_mails_count/static/src/js/res_partner_mails_count_tour.js
-
35res_partner_mails_count/templates.xml
-
2res_partner_mails_count/tests/__init__.py
-
65res_partner_mails_count/tests/test_mail.py
-
17res_partner_mails_count/tests/test_phantom.py
-
2res_partner_mails_count/views/res_partner_mails_count.xml
@ -1,2 +1,4 @@ |
|||
This folder is attached on image building as `custom/` folder in [doobba](https://github.com/Tecnativa/doodba#image-usage). |
|||
Few additional [files](https://github.com/itpp-labs/DINAR/tree/master/embedded-files/.DINAR/image) are attached temporary on image building. |
|||
This folder is attached on image building as `custom/` folder in |
|||
[doobba](https://github.com/Tecnativa/doodba#image-usage). Few additional |
|||
[files](https://github.com/itpp-labs/DINAR/tree/master/embedded-files/.DINAR/image) are |
|||
attached temporary on image building. |
@ -1,29 +1,33 @@ |
|||
/* # Copyright 2018 Kolushov Alexandr <https://it-projects.info/team/KolushovAlexandr> |
|||
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html). */
|
|||
odoo.define('mail_all.tour', function (require) { |
|||
odoo.define("mail_all.tour", function(require) { |
|||
"use strict"; |
|||
|
|||
var tour = require("web_tour.tour"); |
|||
var core = require('web.core'); |
|||
var core = require("web.core"); |
|||
var _t = core._t; |
|||
|
|||
|
|||
var steps = [{ |
|||
var steps = [ |
|||
{ |
|||
trigger: 'a.full[href="#"]', |
|||
content: _t("Click to open app list"), |
|||
position: 'bottom', |
|||
}, { |
|||
position: "bottom", |
|||
}, |
|||
{ |
|||
trigger: 'a.dropdown-item.o_app:contains("Discuss")', |
|||
content: _t("Click to enter menu discuss"), |
|||
position: 'bottom', |
|||
}, { |
|||
position: "bottom", |
|||
}, |
|||
{ |
|||
content: _t("Open All Messages"), |
|||
trigger: '.o_channel_name.mail_all', |
|||
}, { |
|||
trigger: ".o_channel_name.mail_all", |
|||
}, |
|||
{ |
|||
content: _t("Check that All Messages are opened"), |
|||
trigger: '.o_mail_discuss_title_main.o_mail_mailbox_title_all.o_mail_discuss_item.o_active', |
|||
}]; |
|||
|
|||
tour.register('tour_mail_all', { test: true, url: '/web' }, steps); |
|||
trigger: |
|||
".o_mail_discuss_title_main.o_mail_mailbox_title_all.o_mail_discuss_item.o_active", |
|||
}, |
|||
]; |
|||
|
|||
tour.register("tour_mail_all", {test: true, url: "/web"}, steps); |
|||
}); |
@ -1,16 +1,24 @@ |
|||
<?xml version="1.0"?> |
|||
<?xml version="1.0" ?> |
|||
<!--# Copyright 2016 Ivan Yelizariev <https://it-projects.info/team/yelizariev> |
|||
# Copyright 2018 Artyom Losev <https://it-projects.info/team/ArtyomLosev> |
|||
# Copyright 2018 Kolushov Alexandr <https://it-projects.info/team/KolushovAlexandr> |
|||
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html). --> |
|||
<odoo> |
|||
<template id="mail_all_assets_backend" |
|||
name="mail_all_assets_backend" |
|||
inherit_id="web.assets_backend"> |
|||
<template |
|||
id="mail_all_assets_backend" |
|||
name="mail_all_assets_backend" |
|||
inherit_id="web.assets_backend" |
|||
> |
|||
<xpath expr="." position="inside"> |
|||
<link rel="stylesheet" href="/mail_all/static/src/css/mail_all.css"/> |
|||
<script src="/mail_all/static/src/js/mail_all.js" type="text/javascript"></script> |
|||
<script src="/mail_all/static/src/js/test_mail_all.js" type="text/javascript"></script> |
|||
<link rel="stylesheet" href="/mail_all/static/src/css/mail_all.css" /> |
|||
<script |
|||
src="/mail_all/static/src/js/mail_all.js" |
|||
type="text/javascript" |
|||
/> |
|||
<script |
|||
src="/mail_all/static/src/js/test_mail_all.js" |
|||
type="text/javascript" |
|||
/> |
|||
</xpath> |
|||
</template> |
|||
</odoo> |
@ -1,89 +1,92 @@ |
|||
odoo.define('mail_archives.archives', function (require) { |
|||
"use strict"; |
|||
odoo.define("mail_archives.archives", function(require) { |
|||
"use strict"; |
|||
|
|||
var core = require('web.core'); |
|||
var session = require('web.session'); |
|||
var Manager = require('mail.Manager'); |
|||
var Mailbox = require('mail.model.Mailbox'); |
|||
var SearchableThread = require('mail.model.SearchableThread'); |
|||
var core = require("web.core"); |
|||
var session = require("web.session"); |
|||
var Manager = require("mail.Manager"); |
|||
var Mailbox = require("mail.model.Mailbox"); |
|||
var SearchableThread = require("mail.model.SearchableThread"); |
|||
|
|||
var _t = core._t; |
|||
var _t = core._t; |
|||
|
|||
Manager.include({ |
|||
_updateMailboxesFromServer: function (data) { |
|||
var self = this; |
|||
this._super(data); |
|||
if (!_.find(this.getThreads(), function(th){ |
|||
return th.getID() === 'mailbox_channel_archive'; |
|||
})) { |
|||
this._addMailbox({ |
|||
id: 'channel_archive', |
|||
name: _t("Archive"), |
|||
mailboxCounter: 0, |
|||
}); |
|||
} |
|||
}, |
|||
}); |
|||
Manager.include({ |
|||
_updateMailboxesFromServer: function(data) { |
|||
var self = this; |
|||
this._super(data); |
|||
if ( |
|||
!_.find(this.getThreads(), function(th) { |
|||
return th.getID() === "mailbox_channel_archive"; |
|||
}) |
|||
) { |
|||
this._addMailbox({ |
|||
id: "channel_archive", |
|||
name: _t("Archive"), |
|||
mailboxCounter: 0, |
|||
}); |
|||
} |
|||
}, |
|||
}); |
|||
|
|||
SearchableThread.include({ |
|||
_fetchMessages: function (pDomain, loadMore) { |
|||
var self = this; |
|||
if (this._id !== 'mailbox_channel_archive') { |
|||
return this._super(pDomain, loadMore); |
|||
} |
|||
SearchableThread.include({ |
|||
_fetchMessages: function(pDomain, loadMore) { |
|||
var self = this; |
|||
if (this._id !== "mailbox_channel_archive") { |
|||
return this._super(pDomain, loadMore); |
|||
} |
|||
|
|||
// this is a copy-paste from super method
|
|||
var domain = this._getThreadDomain(); |
|||
var cache = this._getCache(pDomain); |
|||
if (pDomain) { |
|||
domain = domain.concat(pDomain || []); |
|||
} |
|||
if (loadMore) { |
|||
var minMessageID = cache.messages[0].getID(); |
|||
domain = [['id', '<', minMessageID]].concat(domain); |
|||
} |
|||
return this._rpc({ |
|||
model: 'mail.message', |
|||
method: 'message_fetch', |
|||
args: [domain], |
|||
kwargs: this._getFetchMessagesKwargs(), |
|||
}).then(function (messages) { |
|||
// except this function. It adds the required thread to downloaded messages
|
|||
_.each(messages, function(m){ |
|||
m.channel_ids.push('mailbox_channel_archive'); |
|||
}); |
|||
if (!cache.allHistoryLoaded) { |
|||
cache.allHistoryLoaded = messages.length < self._FETCH_LIMIT; |
|||
// This is a copy-paste from super method
|
|||
var domain = this._getThreadDomain(); |
|||
var cache = this._getCache(pDomain); |
|||
if (pDomain) { |
|||
domain = domain.concat(pDomain || []); |
|||
} |
|||
cache.loaded = true; |
|||
_.each(messages, function (message) { |
|||
self.call('mail_service', 'addMessage', message, { |
|||
silent: true, |
|||
domain: pDomain, |
|||
if (loadMore) { |
|||
var minMessageID = cache.messages[0].getID(); |
|||
domain = [["id", "<", minMessageID]].concat(domain); |
|||
} |
|||
return this._rpc({ |
|||
model: "mail.message", |
|||
method: "message_fetch", |
|||
args: [domain], |
|||
kwargs: this._getFetchMessagesKwargs(), |
|||
}).then(function(messages) { |
|||
// Except this function. It adds the required thread to downloaded messages
|
|||
_.each(messages, function(m) { |
|||
m.channel_ids.push("mailbox_channel_archive"); |
|||
}); |
|||
if (!cache.allHistoryLoaded) { |
|||
cache.allHistoryLoaded = messages.length < self._FETCH_LIMIT; |
|||
} |
|||
cache.loaded = true; |
|||
_.each(messages, function(message) { |
|||
self.call("mail_service", "addMessage", message, { |
|||
silent: true, |
|||
domain: pDomain, |
|||
}); |
|||
}); |
|||
cache = self._getCache(pDomain || []); |
|||
return cache.messages; |
|||
}); |
|||
cache = self._getCache(pDomain || []); |
|||
return cache.messages; |
|||
}); |
|||
}, |
|||
}); |
|||
}, |
|||
}); |
|||
|
|||
Mailbox.include({ |
|||
_getThreadDomain: function () { |
|||
if (this._id === 'mailbox_channel_archive') { |
|||
return ['|','|', |
|||
['partner_ids', 'in', [session.partner_id]], |
|||
['author_id', 'in', [session.partner_id]], |
|||
['channel_ids.channel_partner_ids', 'in', [session.partner_id]], |
|||
]; |
|||
} |
|||
return this._super(); |
|||
}, |
|||
}); |
|||
|
|||
return { |
|||
'Manager': Manager, |
|||
'Mailbox': Mailbox, |
|||
}; |
|||
Mailbox.include({ |
|||
_getThreadDomain: function() { |
|||
if (this._id === "mailbox_channel_archive") { |
|||
return [ |
|||
"|", |
|||
"|", |
|||
["partner_ids", "in", [session.partner_id]], |
|||
["author_id", "in", [session.partner_id]], |
|||
["channel_ids.channel_partner_ids", "in", [session.partner_id]], |
|||
]; |
|||
} |
|||
return this._super(); |
|||
}, |
|||
}); |
|||
|
|||
return { |
|||
Manager: Manager, |
|||
Mailbox: Mailbox, |
|||
}; |
|||
}); |
@ -1,2 +1 @@ |
|||
|
|||
from . import test_js |
@ -1,12 +1,20 @@ |
|||
<?xml version="1.0"?> |
|||
<?xml version="1.0" ?> |
|||
<openerp> |
|||
<data> |
|||
<template id="res_partner_mails_count_assets_backend" |
|||
name="res_partner_mails_count_assets_backend" |
|||
inherit_id="web.assets_backend"> |
|||
<template |
|||
id="res_partner_mails_count_assets_backend" |
|||
name="res_partner_mails_count_assets_backend" |
|||
inherit_id="web.assets_backend" |
|||
> |
|||
<xpath expr="." position="inside"> |
|||
<link rel="stylesheet" href="/mail_archives/static/src/css/archives.css"/> |
|||
<script src="/mail_archives/static/src/js/archives.js" type="text/javascript"></script> |
|||
<link |
|||
rel="stylesheet" |
|||
href="/mail_archives/static/src/css/archives.css" |
|||
/> |
|||
<script |
|||
src="/mail_archives/static/src/js/archives.js" |
|||
type="text/javascript" |
|||
/> |
|||
</xpath> |
|||
</template> |
|||
</data> |
|||
|
@ -1,3 +1,2 @@ |
|||
|
|||
from . import models |
|||
from . import controllers |
@ -1,28 +1,29 @@ |
|||
|
|||
from openerp import api, models |
|||
from openerp import models |
|||
|
|||
|
|||
class MailMessage(models.Model): |
|||
_inherit = 'mail.message' |
|||
_inherit = "mail.message" |
|||
|
|||
def write(self, values): |
|||
if values.get('needaction_partner_ids'): |
|||
if not values.get('partner_ids'): |
|||
values['partner_ids'] = [] |
|||
for triplet in values.get('needaction_partner_ids'): |
|||
if values.get("needaction_partner_ids"): |
|||
if not values.get("partner_ids"): |
|||
values["partner_ids"] = [] |
|||
for triplet in values.get("needaction_partner_ids"): |
|||
if triplet[0] == 6: |
|||
for id in triplet[2]: |
|||
values['partner_ids'].append((4, id, False)) |
|||
values["partner_ids"].append((4, id, False)) |
|||
return super(MailMessage, self).write(values) |
|||
|
|||
|
|||
class MailComposer(models.TransientModel): |
|||
|
|||
_inherit = 'mail.compose.message' |
|||
_inherit = "mail.compose.message" |
|||
|
|||
def send_mail(self, auto_commit=False): |
|||
res = super(MailComposer, self).send_mail(auto_commit=auto_commit) |
|||
notification = {} |
|||
self.env['bus.bus'].sendone((self._cr.dbname, 'mail_base.mail_sent'), notification) |
|||
self.env["bus.bus"].sendone( |
|||
(self._cr.dbname, "mail_base.mail_sent"), notification |
|||
) |
|||
|
|||
return res |
@ -1,2 +1 @@ |
|||
|
|||
from . import test_default |
@ -1,11 +1,13 @@ |
|||
<?xml version="1.0"?> |
|||
<?xml version="1.0" ?> |
|||
<openerp> |
|||
<data> |
|||
<template id="mail_base_assets_backend" |
|||
name="mail_base_assets_backend" |
|||
inherit_id="web.assets_backend"> |
|||
<template |
|||
id="mail_base_assets_backend" |
|||
name="mail_base_assets_backend" |
|||
inherit_id="web.assets_backend" |
|||
> |
|||
<xpath expr="." position="inside"> |
|||
<script src="/mail_base/static/lib/base.js" type="text/javascript"></script> |
|||
<script src="/mail_base/static/lib/base.js" type="text/javascript" /> |
|||
</xpath> |
|||
</template> |
|||
</data> |
|||
|
@ -1,19 +1,15 @@ |
|||
{ |
|||
'name': 'Check mail immediately', |
|||
'version': '1.0.1', |
|||
'author': 'IT-Projects LLC, Ivan Yelizariev', |
|||
'license': 'LGPL-3', |
|||
"name": "Check mail immediately", |
|||
"version": "1.0.1", |
|||
"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': ['base', 'web', 'fetchmail', 'mail'], |
|||
'data': [ |
|||
'views.xml', |
|||
], |
|||
'qweb': [ |
|||
"static/src/xml/main.xml", |
|||
], |
|||
'installable': False |
|||
"website": "https://twitter.com/yelizariev", |
|||
"price": 9.00, |
|||
"currency": "EUR", |
|||
"depends": ["base", "web", "fetchmail", "mail"], |
|||
"data": ["views.xml",], |
|||
"qweb": ["static/src/xml/main.xml",], |
|||
"installable": False, |
|||
} |
@ -1,8 +1,15 @@ |
|||
<openerp> |
|||
<data> |
|||
<template id="assets_backend_inherited_check_mail" name="Check mail immediately bar" inherit_id="web.assets_backend"> |
|||
<template |
|||
id="assets_backend_inherited_check_mail" |
|||
name="Check mail immediately bar" |
|||
inherit_id="web.assets_backend" |
|||
> |
|||
<xpath expr="." position="inside"> |
|||
<script type="text/javascript" src="/mail_check_immediately/static/src/js/main.js"></script> |
|||
<script |
|||
type="text/javascript" |
|||
src="/mail_check_immediately/static/src/js/main.js" |
|||
/> |
|||
</xpath> |
|||
</template> |
|||
</data> |
|||
|
@ -1,15 +1,18 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<?xml version="1.0" encoding="UTF-8" ?> |
|||
<!--# Copyright 2016 Ildar Nasyrov <https://it-projects.info/team/iledarn> |
|||
# Copyright 2016 Ivan Yelizariev <https://it-projects.info/team/yelizariev> |
|||
# Copyright 2016 Pavel Romanchenko |
|||
# Copyright 2018 Kolushov Alexandr <https://it-projects.info/team/KolushovAlexandr> |
|||
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html).--> |
|||
|
|||
<template> |
|||
<t t-extend="mail.ChatThread.Message"> |
|||
<t t-jquery='p.o_mail_info span:last-child i:first-child' t-operation="before"> |
|||
<i t-if="!message.is_system_notification" t-att-class="'fa fa-exchange oe_move' + (message.is_moved ? ' oe_moved' : '')" |
|||
t-att-data-message-id="message.id" title="Move to thread"/> |
|||
<i |
|||
t-if="!message.is_system_notification" |
|||
t-att-class="'fa fa-exchange oe_move' + (message.is_moved ? ' oe_moved' : '')" |
|||
t-att-data-message-id="message.id" |
|||
title="Move to thread" |
|||
/> |
|||
</t> |
|||
</t> |
|||
</template> |
@ -1,3 +1,2 @@ |
|||
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html). |
|||
from . import test_mail_move |
|||
|
@ -1,19 +1,19 @@ |
|||
# Copyright 2018 Ivan Yelizariev <https://it-projects.info/team/yelizariev> |
|||
# Copyright 2018 Kolushov Alexandr <https://it-projects.info/team/KolushovAlexandr> |
|||
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html). |
|||
from odoo import models, api |
|||
from odoo import models |
|||
|
|||
|
|||
class IrProperty(models.Model): |
|||
_inherit = 'ir.property' |
|||
_inherit = "ir.property" |
|||
|
|||
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'), |
|||
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) |
|||
|
@ -1,16 +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 |
|||
from odoo import fields, models |
|||
|
|||
|
|||
class Message(models.Model): |
|||
_inherit = 'mail.message' |
|||
_inherit = "mail.message" |
|||
|
|||
def _default_mail_server_id(self): |
|||
website = self.env.context.get('website_id') |
|||
website = self.env.context.get("website_id") |
|||
if not website: |
|||
return |
|||
website = self.env['website'].sudo().browse(website) |
|||
website = self.env["website"].sudo().browse(website) |
|||
return website.mail_server_id.id |
|||
|
|||
mail_server_id = fields.Many2one(default=_default_mail_server_id) |
@ -1,10 +1,12 @@ |
|||
# 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 |
|||
from odoo import fields, models |
|||
|
|||
|
|||
class Website(models.Model): |
|||
_inherit = "website" |
|||
|
|||
mail_server_id = fields.Many2one('ir.mail_server', 'Outgoing Mails', help='Default outgoing mail server') |
|||
mail_server_id = fields.Many2one( |
|||
"ir.mail_server", "Outgoing Mails", help="Default outgoing mail server" |
|||
) |
@ -1,10 +1,18 @@ |
|||
# 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 |
|||
from odoo import fields, models |
|||
|
|||
|
|||
class MailTest(models.Model): |
|||
_inherit = 'mail.test.simple' |
|||
_inherit = "mail.test.simple" |
|||
|
|||
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'))) |
|||
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") |
|||
), |
|||
) |
@ -1,13 +1,13 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<?xml version="1.0" encoding="utf-8" ?> |
|||
<!-- Copyright 2018 Ivan Yelizariev <https://it-projects.info/team/yelizariev> |
|||
License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html). --> |
|||
<odoo> |
|||
<record id="view_website_multi_mail_form" model="ir.ui.view"> |
|||
<field name="model">website</field> |
|||
<field name="inherit_id" ref="website.view_website_form"/> |
|||
<field name="inherit_id" ref="website.view_website_form" /> |
|||
<field name="arch" type="xml"> |
|||
<xpath expr="//field[@name='default_lang_id']" position="after"> |
|||
<field name="mail_server_id"/> |
|||
<field name="mail_server_id" /> |
|||
</xpath> |
|||
</field> |
|||
</record> |
|||
|
@ -1,20 +1,22 @@ |
|||
# 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 |
|||
from odoo import api, models |
|||
from odoo.http import request |
|||
|
|||
|
|||
class MailComposer(models.TransientModel): |
|||
|
|||
_inherit = 'mail.compose.message' |
|||
_inherit = "mail.compose.message" |
|||
|
|||
@api.model |
|||
def create(self, vals): |
|||
"""Workaround for https://github.com/odoo/odoo/pull/26589""" |
|||
if 'website_id' not in self.env.context: |
|||
website = request and hasattr(request, 'website') and request.website or None |
|||
if "website_id" not in self.env.context: |
|||
website = ( |
|||
request and hasattr(request, "website") and request.website or None |
|||
) |
|||
if not website: |
|||
website = self.env['website'].get_current_website() |
|||
website = self.env["website"].get_current_website() |
|||
if website: |
|||
self = self.with_context(website_id=website.id) |
|||
return super(MailComposer, self).create(vals) |
@ -1,61 +1,72 @@ |
|||
/* Copyright 2018-2019 Kolushov Alexandr <https://it-projects.info/team/KolushovAlexandr> |
|||
Copyright 2019 Artem Rafailov <https://it-projects.info/team/Ommo73/>
|
|||
License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html).*/
|
|||
odoo.define('mail_private.tour', function(require) { |
|||
"use strict"; |
|||
odoo.define("mail_private.tour", function(require) { |
|||
"use strict"; |
|||
|
|||
var core = require('web.core'); |
|||
var tour = require('web_tour.tour'); |
|||
var core = require("web.core"); |
|||
var tour = require("web_tour.tour"); |
|||
var _t = core._t; |
|||
|
|||
var email = 'mail_private test email'; |
|||
var steps = [tour.STEPS.SHOW_APPS_MENU_ITEM, { |
|||
trigger: '.fa.fa-cog.o_mail_channel_settings', |
|||
content: _t('Select channel settings'), |
|||
position: 'bottom', |
|||
}, { |
|||
var email = "mail_private test email"; |
|||
var steps = [ |
|||
tour.STEPS.SHOW_APPS_MENU_ITEM, |
|||
{ |
|||
trigger: ".fa.fa-cog.o_mail_channel_settings", |
|||
content: _t("Select channel settings"), |
|||
position: "bottom", |
|||
}, |
|||
{ |
|||
trigger: '.nav-link:contains("Members")', |
|||
content: _t('Go to the list of subscribers'), |
|||
position: 'bottom', |
|||
}, { |
|||
content: _t("Go to the list of subscribers"), |
|||
position: "bottom", |
|||
}, |
|||
{ |
|||
trigger: '.o_data_cell:contains("YourCompany, Marc Demo")', |
|||
content: _t("Select a user"), |
|||
position: "bottom", |
|||
}, { |
|||
}, |
|||
{ |
|||
trigger: '.o_form_uri.o_field_widget:contains("YourCompany, Marc Demo")', |
|||
content: _t("Go to user page"), |
|||
position: "bottom" |
|||
}, { |
|||
position: "bottom", |
|||
}, |
|||
{ |
|||
trigger: "button.oe_compose_post_private", |
|||
content: _t("Click on Private mail creating button"), |
|||
position: "bottom" |
|||
}, { |
|||
// for some reason (due to tricky renderings) button.oe_composer_uncheck could not be find by the tour manager
|
|||
position: "bottom", |
|||
}, |
|||
{ |
|||
// For some reason (due to tricky renderings) button.oe_composer_uncheck could not be find by the tour manager
|
|||
trigger: ".o_control_panel.o_breadcrumb_full li.active", |
|||
content: _t("Dummy action"), |
|||
}, { |
|||
}, |
|||
{ |
|||
trigger: "button.oe_composer_uncheck", |
|||
extra_trigger: "button.oe_composer_uncheck", |
|||
content: _t("Uncheck all Followers"), |
|||
timeout: 10000, |
|||
}, { |
|||
}, |
|||
{ |
|||
trigger: "div.o_composer_suggested_partners", |
|||
content: _t("Check the first one"), |
|||
}, { |
|||
}, |
|||
{ |
|||
trigger: "textarea.o_composer_text_field:first", |
|||
content: _t("Write some email"), |
|||
run: function() { |
|||
$('textarea.o_composer_text_field:first').val(email); |
|||
$("textarea.o_composer_text_field:first").val(email); |
|||
}, |
|||
}, { |
|||
}, |
|||
{ |
|||
trigger: ".o_composer_send .o_composer_button_send", |
|||
content: _t("Send email"), |
|||
}, { |
|||
}, |
|||
{ |
|||
trigger: ".o_mail_thread .o_thread_message:contains(" + email + ")", |
|||
content: _t("Send email"), |
|||
} |
|||
}, |
|||
]; |
|||
|
|||
tour.register('mail_private_tour', { test: true, url: '/web' }, steps); |
|||
|
|||
tour.register("mail_private_tour", {test: true, url: "/web"}, steps); |
|||
}); |
@ -1,19 +1,22 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<?xml version="1.0" encoding="utf-8" ?> |
|||
<!--Copyright 2016 x620 <https://github.com/x620> |
|||
Copyright 2019 Artem Rafailov <https://it-projects.info/team/Ommo73/> |
|||
License LGPL-3.0 (https://www.gnu.org/licenses/lgpl.html).--> |
|||
<odoo> |
|||
<template |
|||
id="assets_backend" |
|||
name="mail_private_assets_backend" |
|||
inherit_id="web.assets_backend"> |
|||
id="assets_backend" |
|||
name="mail_private_assets_backend" |
|||
inherit_id="web.assets_backend" |
|||
> |
|||
<xpath expr="." position="inside"> |
|||
<script |
|||
type="text/javascript" |
|||
src="/mail_private/static/src/js/mail_private.js"></script> |
|||
type="text/javascript" |
|||
src="/mail_private/static/src/js/mail_private.js" |
|||
/> |
|||
<script |
|||
type="text/javascript" |
|||
src="/mail_private/static/src/js/test_private.js"></script> |
|||
type="text/javascript" |
|||
src="/mail_private/static/src/js/test_private.js" |
|||
/> |
|||
</xpath> |
|||
</template> |
|||
</odoo> |
@ -1,18 +1,16 @@ |
|||
{ |
|||
'name': "Mail Recovery", |
|||
'summary': """Backup and recover unsent message""", |
|||
'author': "IT-Projects LLC, Ildar Nasyrov", |
|||
'license': 'LGPL-3', |
|||
"name": "Mail Recovery", |
|||
"summary": """Backup and recover unsent message""", |
|||
"author": "IT-Projects LLC, Ildar Nasyrov", |
|||
"license": "LGPL-3", |
|||
"price": 95.00, |
|||
"currency": "EUR", |
|||
"support": "apps@it-projects.info", |
|||
'website': "https://twitter.com/nasyrov_ildar", |
|||
'category': 'Discuss', |
|||
'images': ['images/mail_recovery.png'], |
|||
'version': '1.0.0', |
|||
'depends': ['mail'], |
|||
'data': [ |
|||
'data.xml', |
|||
], |
|||
"website": "https://twitter.com/nasyrov_ildar", |
|||
"category": "Discuss", |
|||
"images": ["images/mail_recovery.png"], |
|||
"version": "1.0.0", |
|||
"depends": ["mail"], |
|||
"data": ["data.xml",], |
|||
"installable": False, |
|||
} |
@ -1,9 +1,16 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<?xml version="1.0" encoding="utf-8" ?> |
|||
<openerp> |
|||
<data> |
|||
<template id="assets_backend" name="message storage" inherit_id="web.assets_backend"> |
|||
<template |
|||
id="assets_backend" |
|||
name="message storage" |
|||
inherit_id="web.assets_backend" |
|||
> |
|||
<xpath expr="." position="inside"> |
|||
<script type="text/javascript" src="/mail_recovery/static/src/js/mail_recovery.js"></script> |
|||
<script |
|||
type="text/javascript" |
|||
src="/mail_recovery/static/src/js/mail_recovery.js" |
|||
/> |
|||
</xpath> |
|||
</template> |
|||
</data> |
|||
|
@ -1,51 +1,51 @@ |
|||
odoo.define('mail_reply.reply', function (require) { |
|||
"use strict"; |
|||
odoo.define("mail_reply.reply", function(require) { |
|||
"use strict"; |
|||
|
|||
var core = require('web.core'); |
|||
var chat_manager = require('mail_base.base').chat_manager; |
|||
var core = require("web.core"); |
|||
var chat_manager = require("mail_base.base").chat_manager; |
|||
|
|||
var ChatAction = core.action_registry.get('mail.chat.instant_messaging'); |
|||
var ChatAction = core.action_registry.get("mail.chat.instant_messaging"); |
|||
|
|||
ChatAction.include({ |
|||
_selectMessage: function (message_id) { |
|||
this._super.apply(this, arguments); |
|||
var message = chat_manager.get_message(message_id); |
|||
var subject = ''; |
|||
if (message.record_name){ |
|||
subject = "Re: " + message.record_name; |
|||
} else if (message.subject){ |
|||
subject = "Re: " + message.subject; |
|||
} |
|||
this.extended_composer.set_subject(subject); |
|||
}, |
|||
ChatAction.include({ |
|||
_selectMessage: function(message_id) { |
|||
this._super.apply(this, arguments); |
|||
var message = chat_manager.get_message(message_id); |
|||
var subject = ""; |
|||
if (message.record_name) { |
|||
subject = "Re: " + message.record_name; |
|||
} else if (message.subject) { |
|||
subject = "Re: " + message.subject; |
|||
} |
|||
this.extended_composer.set_subject(subject); |
|||
}, |
|||
|
|||
_onPostMessage: function (message) { |
|||
var self = this; |
|||
var options = this.selected_message |
|||
? {} |
|||
: {channel_id: this.channel.id}; |
|||
if (this.selected_message) { |
|||
message.subtype = 'mail.mt_comment'; |
|||
message.subtype_id = false; |
|||
message.message_type = 'comment'; |
|||
message.content_subtype = 'html'; |
|||
_onPostMessage: function(message) { |
|||
var self = this; |
|||
var options = this.selected_message ? {} : {channel_id: this.channel.id}; |
|||
if (this.selected_message) { |
|||
message.subtype = "mail.mt_comment"; |
|||
message.subtype_id = false; |
|||
message.message_type = "comment"; |
|||
message.content_subtype = "html"; |
|||
|
|||
options.model = this.selected_message.model; |
|||
options.res_id = this.selected_message.res_id; |
|||
options.parent_id = this.selected_message.id; |
|||
} |
|||
chat_manager.post_message(message, options). |
|||
then(function () { |
|||
options.model = this.selected_message.model; |
|||
options.res_id = this.selected_message.res_id; |
|||
options.parent_id = this.selected_message.id; |
|||
} |
|||
chat_manager.post_message(message, options).then(function() { |
|||
if (self.selected_message) { |
|||
self._renderSnackbar('mail.chat.MessageSentSnackbar', {record_name: self.selected_message.record_name}, 5000); |
|||
self._renderSnackbar( |
|||
"mail.chat.MessageSentSnackbar", |
|||
{record_name: self.selected_message.record_name}, |
|||
5000 |
|||
); |
|||
self._unselectMessage(); |
|||
} else { |
|||
self.thread.scroll_to(); |
|||
} |
|||
}); |
|||
} |
|||
}); |
|||
|
|||
return chat_manager; |
|||
}, |
|||
}); |
|||
|
|||
return chat_manager; |
|||
}); |
@ -1,10 +1,16 @@ |
|||
<?xml version="1.0" encoding="UTF-8"?> |
|||
<?xml version="1.0" encoding="UTF-8" ?> |
|||
<template> |
|||
<t t-extend="mail.ChatThread.Message"> |
|||
<t t-jquery='i[class="fa fa-reply o_thread_icon o_thread_message_reply"]' t-operation="replace"> |
|||
<i t-if="message.author_id != 'ODOOBOT' && message.model != 'mail.channel' && options.display_reply_icon" |
|||
<t |
|||
t-jquery='i[class="fa fa-reply o_thread_icon o_thread_message_reply"]' |
|||
t-operation="replace" |
|||
> |
|||
<i |
|||
t-if="message.author_id != 'ODOOBOT' && message.model != 'mail.channel' && options.display_reply_icon" |
|||
class="fa fa-reply o_thread_icon o_thread_message_reply" |
|||
t-att-data-message-id="message.id" title="Reply"/> |
|||
t-att-data-message-id="message.id" |
|||
title="Reply" |
|||
/> |
|||
</t> |
|||
</t> |
|||
</template> |
@ -1,11 +1,16 @@ |
|||
<?xml version="1.0"?> |
|||
<?xml version="1.0" ?> |
|||
<openerp> |
|||
<data> |
|||
<template id="mail_reply_assets_backend" |
|||
name="mail_reply_assets_backend" |
|||
inherit_id="web.assets_backend"> |
|||
<template |
|||
id="mail_reply_assets_backend" |
|||
name="mail_reply_assets_backend" |
|||
inherit_id="web.assets_backend" |
|||
> |
|||
<xpath expr="." position="inside"> |
|||
<script src="/mail_reply/static/src/js/mail_reply.js" type="text/javascript"></script> |
|||
<script |
|||
src="/mail_reply/static/src/js/mail_reply.js" |
|||
type="text/javascript" |
|||
/> |
|||
</xpath> |
|||
</template> |
|||
</data> |
|||
|
@ -1,2 +1 @@ |
|||
|
|||
from . import test_default |
@ -1,45 +1,43 @@ |
|||
from odoo import api, models, fields |
|||
from odoo import api, fields, models |
|||
|
|||
|
|||
class MailMessage(models.Model): |
|||
_inherit = 'mail.message' |
|||
_inherit = "mail.message" |
|||
|
|||
sent = fields.Boolean('Sent', compute="_compute_sent", help='Was message sent to someone', store=True) |
|||
sent = fields.Boolean( |
|||
"Sent", compute="_compute_sent", help="Was message sent to someone", store=True |
|||
) |
|||
|
|||
@api.depends('author_id', 'partner_ids', 'channel_ids') |
|||
@api.depends("author_id", "partner_ids", "channel_ids") |
|||
def _compute_sent(self): |
|||
for r in self: |
|||
r_sudo = r.sudo() |
|||
recipient_ids = r_sudo.partner_ids |
|||
author_id = r_sudo.author_id |
|||
res_id = r_sudo.model and r_sudo.res_id and r_sudo.env[r_sudo.model].browse(r_sudo.res_id) |
|||
res_id = ( |
|||
r_sudo.model |
|||
and r_sudo.res_id |
|||
and r_sudo.env[r_sudo.model].browse(r_sudo.res_id) |
|||
) |
|||
sent = author_id and ( |
|||
len(recipient_ids) > 1 |
|||
or ( |
|||
len(recipient_ids) == 1 |
|||
and recipient_ids[0].id != author_id.id |
|||
) |
|||
or ( |
|||
len(r_sudo.channel_ids) |
|||
) |
|||
or ( |
|||
res_id |
|||
and len(res_id.message_partner_ids - author_id) > 0 |
|||
) |
|||
or (len(recipient_ids) == 1 and recipient_ids[0].id != author_id.id) |
|||
or (len(r_sudo.channel_ids)) |
|||
or (res_id and len(res_id.message_partner_ids - author_id) > 0) |
|||
) |
|||
r.sent = sent |
|||
|
|||
def message_format(self): |
|||
message_values = super(MailMessage, self).message_format() |
|||
message_index = {message['id']: message for message in message_values} |
|||
message_index = {message["id"]: message for message in message_values} |
|||
for item in self: |
|||
msg = message_index.get(item.id) |
|||
if msg: |
|||
msg['sent'] = item.sent |
|||
msg["sent"] = item.sent |
|||
return message_values |
|||
|
|||
|
|||
class MailComposeMessage(models.TransientModel): |
|||
|
|||
_inherit = 'mail.compose.message' |
|||
sent = fields.Boolean('Sent', help='dummy field to fix inherit error') |
|||
_inherit = "mail.compose.message" |
|||
sent = fields.Boolean("Sent", help="dummy field to fix inherit error") |
@ -1,88 +1,89 @@ |
|||
odoo.define('mail_sent.sent', function (require) { |
|||
"use strict"; |
|||
odoo.define("mail_sent.sent", function(require) { |
|||
"use strict"; |
|||
|
|||
var core = require('web.core'); |
|||
var session = require('web.session'); |
|||
var Manager = require('mail.Manager'); |
|||
var Mailbox = require('mail.model.Mailbox'); |
|||
var SearchableThread = require('mail.model.SearchableThread'); |
|||
var core = require("web.core"); |
|||
var session = require("web.session"); |
|||
var Manager = require("mail.Manager"); |
|||
var Mailbox = require("mail.model.Mailbox"); |
|||
var SearchableThread = require("mail.model.SearchableThread"); |
|||
|
|||
var _t = core._t; |
|||
var _t = core._t; |
|||
|
|||
Manager.include({ |
|||
_updateMailboxesFromServer: function (data) { |
|||
var self = this; |
|||
this._super(data); |
|||
if (!_.find(this.getThreads(), function(th){ |
|||
return th.getID() === 'mailbox_channel_sent'; |
|||
})) { |
|||
this._addMailbox({ |
|||
id: 'channel_sent', |
|||
name: _t("Sent Messages"), |
|||
mailboxCounter: 0, |
|||
}); |
|||
} |
|||
}, |
|||
}); |
|||
Manager.include({ |
|||
_updateMailboxesFromServer: function(data) { |
|||
var self = this; |
|||
this._super(data); |
|||
if ( |
|||
!_.find(this.getThreads(), function(th) { |
|||
return th.getID() === "mailbox_channel_sent"; |
|||
}) |
|||
) { |
|||
this._addMailbox({ |
|||
id: "channel_sent", |
|||
name: _t("Sent Messages"), |
|||
mailboxCounter: 0, |
|||
}); |
|||
} |
|||
}, |
|||
}); |
|||
|
|||
SearchableThread.include({ |
|||
_fetchMessages: function (pDomain, loadMore) { |
|||
var self = this; |
|||
if (this._id !== 'mailbox_channel_sent') { |
|||
return this._super(pDomain, loadMore); |
|||
} |
|||
SearchableThread.include({ |
|||
_fetchMessages: function(pDomain, loadMore) { |
|||
var self = this; |
|||
if (this._id !== "mailbox_channel_sent") { |
|||
return this._super(pDomain, loadMore); |
|||
} |
|||
|
|||
// this is a copy-paste from super method
|
|||
var domain = this._getThreadDomain(); |
|||
var cache = this._getCache(pDomain); |
|||
if (pDomain) { |
|||
domain = domain.concat(pDomain || []); |
|||
} |
|||
if (loadMore) { |
|||
var minMessageID = cache.messages[0].getID(); |
|||
domain = [['id', '<', minMessageID]].concat(domain); |
|||
} |
|||
return this._rpc({ |
|||
model: 'mail.message', |
|||
method: 'message_fetch', |
|||
args: [domain], |
|||
kwargs: this._getFetchMessagesKwargs(), |
|||
}).then(function (messages) { |
|||
// except this function. It adds the required thread to downloaded messages
|
|||
_.each(messages, function(m){ |
|||
m.channel_ids.push('mailbox_channel_sent'); |
|||
}); |
|||
if (!cache.allHistoryLoaded) { |
|||
cache.allHistoryLoaded = messages.length < self._FETCH_LIMIT; |
|||
// This is a copy-paste from super method
|
|||
var domain = this._getThreadDomain(); |
|||
var cache = this._getCache(pDomain); |
|||
if (pDomain) { |
|||
domain = domain.concat(pDomain || []); |
|||
} |
|||
cache.loaded = true; |
|||
_.each(messages, function (message) { |
|||
self.call('mail_service', 'addMessage', message, { |
|||
silent: true, |
|||
domain: pDomain, |
|||
if (loadMore) { |
|||
var minMessageID = cache.messages[0].getID(); |
|||
domain = [["id", "<", minMessageID]].concat(domain); |
|||
} |
|||
return this._rpc({ |
|||
model: "mail.message", |
|||
method: "message_fetch", |
|||
args: [domain], |
|||
kwargs: this._getFetchMessagesKwargs(), |
|||
}).then(function(messages) { |
|||
// Except this function. It adds the required thread to downloaded messages
|
|||
_.each(messages, function(m) { |
|||
m.channel_ids.push("mailbox_channel_sent"); |
|||
}); |
|||
if (!cache.allHistoryLoaded) { |
|||
cache.allHistoryLoaded = messages.length < self._FETCH_LIMIT; |
|||
} |
|||
cache.loaded = true; |
|||
_.each(messages, function(message) { |
|||
self.call("mail_service", "addMessage", message, { |
|||
silent: true, |
|||
domain: pDomain, |
|||
}); |
|||
}); |
|||
cache = self._getCache(pDomain || []); |
|||
return cache.messages; |
|||
}); |
|||
cache = self._getCache(pDomain || []); |
|||
return cache.messages; |
|||
}); |
|||
}, |
|||
}); |
|||
}, |
|||
}); |
|||
|
|||
Mailbox.include({ |
|||
_getThreadDomain: function () { |
|||
if (this._id === 'mailbox_channel_sent') { |
|||
return [ |
|||
['sent', '=', true], |
|||
['author_id.user_ids', 'in', [session.uid]] |
|||
]; |
|||
} |
|||
return this._super(); |
|||
}, |
|||
}); |
|||
|
|||
return { |
|||
'Manager': Manager, |
|||
'Mailbox': Mailbox, |
|||
}; |
|||
Mailbox.include({ |
|||
_getThreadDomain: function() { |
|||
if (this._id === "mailbox_channel_sent") { |
|||
return [ |
|||
["sent", "=", true], |
|||
["author_id.user_ids", "in", [session.uid]], |
|||
]; |
|||
} |
|||
return this._super(); |
|||
}, |
|||
}); |
|||
|
|||
return { |
|||
Manager: Manager, |
|||
Mailbox: Mailbox, |
|||
}; |
|||
}); |
@ -1,2 +1 @@ |
|||
|
|||
from . import test_js |
@ -1,12 +1,14 @@ |
|||
<?xml version="1.0"?> |
|||
<?xml version="1.0" ?> |
|||
<openerp> |
|||
<data> |
|||
<template id="mail_sent_assets_backend" |
|||
name="mail_sent_assets_backend" |
|||
inherit_id="web.assets_backend"> |
|||
<template |
|||
id="mail_sent_assets_backend" |
|||
name="mail_sent_assets_backend" |
|||
inherit_id="web.assets_backend" |
|||
> |
|||
<xpath expr="." position="inside"> |
|||
<link rel="stylesheet" href="/mail_sent/static/src/css/sent.css"/> |
|||
<script src="/mail_sent/static/src/js/sent.js" type="text/javascript"></script> |
|||
<link rel="stylesheet" href="/mail_sent/static/src/css/sent.css" /> |
|||
<script src="/mail_sent/static/src/js/sent.js" type="text/javascript" /> |
|||
</xpath> |
|||
</template> |
|||
</data> |
|||
|
@ -1,11 +1,13 @@ |
|||
<?xml version="1.0"?> |
|||
<?xml version="1.0" ?> |
|||
<openerp> |
|||
<data> |
|||
<template id="mail_to_assets_backend" |
|||
name="mail_to_assets_backend" |
|||
inherit_id="web.assets_backend"> |
|||
<template |
|||
id="mail_to_assets_backend" |
|||
name="mail_to_assets_backend" |
|||
inherit_id="web.assets_backend" |
|||
> |
|||
<xpath expr="." position="inside"> |
|||
<link rel="stylesheet" href="/mail_to/static/src/css/mail_to.css"/> |
|||
<link rel="stylesheet" href="/mail_to/static/src/css/mail_to.css" /> |
|||
</xpath> |
|||
</template> |
|||
</data> |
|||
|
@ -1,16 +1,16 @@ |
|||
import re |
|||
|
|||
from odoo import http |
|||
from odoo.http import request |
|||
import re |
|||
|
|||
|
|||
class MailMailgun(http.Controller): |
|||
|
|||
@http.route('/mailgun/notify', auth='public', type='http', csrf=False) |
|||
@http.route("/mailgun/notify", auth="public", type="http", csrf=False) |
|||
def mailgun_notify(self, **kw): |
|||
# mailgun notification in json format |
|||
message_url = kw.get('message-url') |
|||
if not re.match('^https://[^/]*api.mailgun.net/', message_url): |
|||
message_url = kw.get("message-url") |
|||
if not re.match("^https://[^/]*api.mailgun.net/", message_url): |
|||
# simple security check failed |
|||
raise Exception('wrong message-url') |
|||
request.env['mail.thread'].sudo().mailgun_fetch_message(message_url) |
|||
return 'ok' |
|||
raise Exception("wrong message-url") |
|||
request.env["mail.thread"].sudo().mailgun_fetch_message(message_url) |
|||
return "ok" |
@ -1,15 +1,15 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<?xml version="1.0" encoding="utf-8" ?> |
|||
<openerp> |
|||
<data noupdate="1"> |
|||
<record id="mailgun_domain_verification" model="ir.cron"> |
|||
<field name="name">Mailgun - domain verification request</field> |
|||
<field name="model_id" ref="model_ir_config_parameter"/> |
|||
<field name="model_id" ref="model_ir_config_parameter" /> |
|||
<field name="interval_number">10</field> |
|||
<field name="interval_type">minutes</field> |
|||
<field name="numbercall">10</field> |
|||
<field name="state">code</field> |
|||
<field name="code">model.mailgun_verify()</field> |
|||
<field name="doall" eval="True"/> |
|||
<field name="doall" eval="True" /> |
|||
</record> |
|||
</data> |
|||
</openerp> |
@ -1,24 +1,27 @@ |
|||
import logging |
|||
|
|||
import requests |
|||
import simplejson |
|||
from openerp import api, models |
|||
|
|||
from openerp import models, api |
|||
|
|||
import logging |
|||
_logger = logging.getLogger(__name__) |
|||
|
|||
|
|||
class IrConfigParameter(models.Model): |
|||
_inherit = ['ir.config_parameter'] |
|||
_inherit = ["ir.config_parameter"] |
|||
|
|||
@api.model |
|||
def mailgun_verify(self): |
|||
verified = self.sudo().get_param('mailgun.verified') |
|||
verified = self.sudo().get_param("mailgun.verified") |
|||
if verified: |
|||
return |
|||
api_key = self.sudo().get_param('mailgun.apikey') |
|||
mail_domain = self.sudo().get_param('mail.catchall.domain') |
|||
api_key = self.sudo().get_param("mailgun.apikey") |
|||
mail_domain = self.sudo().get_param("mail.catchall.domain") |
|||
if api_key and mail_domain: |
|||
url = "https://api.mailgun.net/v3/domains/%s/verify" % mail_domain |
|||
res = requests.put(url, auth=("api", api_key)) |
|||
if res.status_code == 200 and simplejson.loads(res.text)["domain"]["state"] == "active": |
|||
self.sudo().set_param('mailgun.verified', '1') |
|||
if ( |
|||
res.status_code == 200 |
|||
and simplejson.loads(res.text)["domain"]["state"] == "active" |
|||
): |
|||
self.sudo().set_param("mailgun.verified", "1") |
@ -1,17 +1,22 @@ |
|||
import requests |
|||
import logging |
|||
|
|||
from odoo import models, api |
|||
import requests |
|||
|
|||
from odoo import api, models |
|||
|
|||
import logging |
|||
_logger = logging.getLogger(__name__) |
|||
|
|||
|
|||
class MailThread(models.AbstractModel): |
|||
_inherit = 'mail.thread' |
|||
_inherit = "mail.thread" |
|||
|
|||
@api.model |
|||
def mailgun_fetch_message(self, message_url): |
|||
api_key = self.env['ir.config_parameter'].sudo().get_param('mailgun.apikey') |
|||
res = requests.get(message_url, headers={'Accept': 'message/rfc2822'}, auth=('api', api_key), verify=False) |
|||
self.message_process(False, res.json().get('body-mime')) |
|||
api_key = self.env["ir.config_parameter"].sudo().get_param("mailgun.apikey") |
|||
res = requests.get( |
|||
message_url, |
|||
headers={"Accept": "message/rfc2822"}, |
|||
auth=("api", api_key), |
|||
verify=False, |
|||
) |
|||
self.message_process(False, res.json().get("body-mime")) |
@ -1,17 +1,15 @@ |
|||
{ |
|||
'name': "Aggregate messages from company's contacts", |
|||
'version': '1.0.0', |
|||
'author': 'IT-Projects LLC, Ivan Yelizariev', |
|||
'license': 'LGPL-3', |
|||
"name": "Aggregate messages from company's contacts", |
|||
"version": "1.0.0", |
|||
"author": "IT-Projects LLC, Ivan Yelizariev", |
|||
"license": "LGPL-3", |
|||
"price": 35.00, |
|||
"currency": "EUR", |
|||
'category': 'Discuss', |
|||
"category": "Discuss", |
|||
"support": "apps@it-projects.info", |
|||
'website': 'https://twitter.com/yelizariev', |
|||
'images': ['images/child.png', 'images/parent.png'], |
|||
'depends': ['mail'], |
|||
'data': [ |
|||
'views.xml', |
|||
], |
|||
'installable': False |
|||
"website": "https://twitter.com/yelizariev", |
|||
"images": ["images/child.png", "images/parent.png"], |
|||
"depends": ["mail"], |
|||
"data": ["views.xml",], |
|||
"installable": False, |
|||
} |
@ -1,17 +1,19 @@ |
|||
from openerp import api |
|||
from openerp import models |
|||
|
|||
|
|||
class Partner(models.Model): |
|||
_inherit = 'res.partner' |
|||
_inherit = "res.partner" |
|||
|
|||
def read(self, fields=None, load='_classic_read'): |
|||
def read(self, fields=None, load="_classic_read"): |
|||
res = super(Partner, self).read(fields=fields, load=load) |
|||
if fields and 'message_ids' in fields: |
|||
if fields and "message_ids" in fields: |
|||
for vals in res: |
|||
partner = self.browse(vals['id']) |
|||
partner = self.browse(vals["id"]) |
|||
if not partner.is_company: |
|||
continue |
|||
domain = [('model', '=', 'res.partner'), ('res_id', 'in', [partner.id] + partner.child_ids.ids)] |
|||
vals['message_ids'] = self.env['mail.message'].search(domain).ids |
|||
domain = [ |
|||
("model", "=", "res.partner"), |
|||
("res_id", "in", [partner.id] + partner.child_ids.ids), |
|||
] |
|||
vals["message_ids"] = self.env["mail.message"].search(domain).ids |
|||
return res |
@ -1,3 +1,3 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<?xml version="1.0" encoding="utf-8" ?> |
|||
<openerp><data> |
|||
</data></openerp> |
@ -1,16 +1,21 @@ |
|||
|
|||
from openerp import models, fields, api |
|||
from openerp import fields, models |
|||
|
|||
|
|||
class ResPartner(models.Model): |
|||
_inherit = 'res.partner' |
|||
_inherit = "res.partner" |
|||
mails_to = fields.Integer(compute="_compute_mails_to") |
|||
mails_from = fields.Integer(compute="_compute_mails_from") |
|||
|
|||
def _compute_mails_to(self): |
|||
for r in self: |
|||
r.mails_to = self.env['mail.message'].sudo().search_count([('partner_ids', 'in', r.id)]) |
|||
r.mails_to = ( |
|||
self.env["mail.message"] |
|||
.sudo() |
|||
.search_count([("partner_ids", "in", r.id)]) |
|||
) |
|||
|
|||
def _compute_mails_from(self): |
|||
for r in self: |
|||
r.mails_from = self.env['mail.message'].sudo().search_count([('author_id', '=', r.id)]) |
|||
r.mails_from = ( |
|||
self.env["mail.message"].sudo().search_count([("author_id", "=", r.id)]) |
|||
) |
@ -1,36 +1,38 @@ |
|||
odoo.define('res_partner_mails_count.res_partner_mails_count_tour', function (require) { |
|||
'use strict'; |
|||
var Core = require('web.core'); |
|||
var Tour = require('web.Tour'); |
|||
odoo.define("res_partner_mails_count.res_partner_mails_count_tour", function(require) { |
|||
"use strict"; |
|||
var Core = require("web.core"); |
|||
var Tour = require("web.Tour"); |
|||
var _t = Core._t; |
|||
|
|||
Tour.register({ |
|||
id: 'mails_count_tour', |
|||
id: "mails_count_tour", |
|||
name: _t("Mails count Tour"), |
|||
mode: 'test', |
|||
path: '/web?res_partner_mails_count=tutorial#id=3&view_type=form&model=res.partner', |
|||
mode: "test", |
|||
path: |
|||
"/web?res_partner_mails_count=tutorial#id=3&view_type=form&model=res.partner", |
|||
steps: [ |
|||
{ |
|||
title: _t("Mails count tutorial"), |
|||
content: _t("Let's see how mails count work."), |
|||
popover: { next: _t("Start Tutorial"), end: _t("Skip") }, |
|||
title: _t("Mails count tutorial"), |
|||
content: _t("Let's see how mails count work."), |
|||
popover: {next: _t("Start Tutorial"), end: _t("Skip")}, |
|||
}, |
|||
{ |
|||
title: _t("New fields"), |
|||
content: _t("Here is new fields with mails counters. Press one of it."), |
|||
element: '.mails_to', |
|||
waitFor: '.mails_to:visible', |
|||
title: _t("New fields"), |
|||
content: _t("Here is new fields with mails counters. Press one of it."), |
|||
element: ".mails_to", |
|||
waitFor: ".mails_to:visible", |
|||
}, |
|||
{ |
|||
title: _t("Done"), |
|||
placement: 'top', |
|||
waitNot: '.mails_to:visible', |
|||
waitFor: '.o_mail_thread', |
|||
element: '.o_mail_thread', |
|||
content: _t("Message are found. <br/>Enjoy your day! <br/> <br/><a href='https://www.it-projects.info/apps' target='_blank'>IT-Projects LLC</a> team "), |
|||
placement: "top", |
|||
waitNot: ".mails_to:visible", |
|||
waitFor: ".o_mail_thread", |
|||
element: ".o_mail_thread", |
|||
content: _t( |
|||
"Message are found. <br/>Enjoy your day! <br/> <br/><a href='https://www.it-projects.info/apps' target='_blank'>IT-Projects LLC</a> team " |
|||
), |
|||
popover: {next: _t("Close Tutorial")}, |
|||
}, |
|||
] |
|||
], |
|||
}); |
|||
|
|||
}); |
@ -1,3 +1,3 @@ |
|||
|
|||
from . import test_mail |
|||
|
|||
# from . import test_phantom |
Write
Preview
Loading…
Cancel
Save
Reference in new issue