Skip to content

Commit 1a04f9c

Browse files
[ADD] mail_ux: new module with new features
1 parent 4751a1d commit 1a04f9c

File tree

9 files changed

+292
-0
lines changed

9 files changed

+292
-0
lines changed

mail_ux/README.rst

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
.. |company| replace:: ADHOC SA
2+
3+
.. |company_logo| image:: https://raw.githubusercontent.com/ingadhoc/maintainer-tools/master/resources/adhoc-logo.png
4+
:alt: ADHOC SA
5+
:target: https://www.adhoc.com.ar
6+
7+
.. |icon| image:: https://raw.githubusercontent.com/ingadhoc/maintainer-tools/master/resources/adhoc-icon.png
8+
9+
.. image:: https://img.shields.io/badge/license-AGPL--3-blue.png
10+
:target: https://www.gnu.org/licenses/agpl
11+
:alt: License: AGPL-3
12+
13+
=======
14+
Mail UX
15+
=======
16+
17+
Several Improvements:
18+
* Only internal user can be mentioned in notes
19+
* Always send email with delay
20+
21+
22+
Installation
23+
============
24+
25+
Only install the module.
26+
27+
Configuration
28+
=============
29+
30+
There is nothing to configure.
31+
32+
Usage
33+
=====
34+
35+
.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas
36+
:alt: Try me on Runbot
37+
:target: http://runbot.adhoc.com.ar/
38+
39+
Bug Tracker
40+
===========
41+
42+
Bugs are tracked on `GitHub Issues
43+
<https://github.com/ingadhoc/miscellaneous/issues>`_. In case of trouble, please
44+
check there if your issue has already been reported. If you spotted it first,
45+
help us smashing it by providing a detailed and welcomed feedback.
46+
47+
Credits
48+
=======
49+
50+
Images
51+
------
52+
53+
* |company| |icon|
54+
55+
Contributors
56+
------------
57+
58+
Maintainer
59+
----------
60+
61+
|company_logo|
62+
63+
This module is maintained by the |company|.
64+
65+
To contribute to this module, please visit https://www.adhoc.com.ar.

mail_ux/__init__.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
##############################################################################
2+
# For copyright and license notices, see __manifest__.py file in module root
3+
# directory
4+
##############################################################################
5+
from . import models

mail_ux/__manifest__.py

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
##############################################################################
2+
#
3+
# Copyright (C) 2019 ADHOC SA (http://www.adhoc.com.ar)
4+
# All Rights Reserved.
5+
#
6+
# This program is free software: you can redistribute it and/or modify
7+
# it under the terms of the GNU Affero General Public License as
8+
# published by the Free Software Foundation, either version 3 of the
9+
# License, or (at your option) any later version.
10+
#
11+
# This program is distributed in the hope that it will be useful,
12+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
# GNU Affero General Public License for more details.
15+
#
16+
# You should have received a copy of the GNU Affero General Public License
17+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
18+
#
19+
##############################################################################
20+
{
21+
'name': 'Mail UX',
22+
'version': "18.0.1.0.0",
23+
'category': 'Base',
24+
'sequence': 14,
25+
'summary': '',
26+
'author': 'ADHOC SA',
27+
'website': 'www.adhoc.com.ar',
28+
'license': 'AGPL-3',
29+
'images': [
30+
],
31+
'assets': {
32+
'web.assets_backend': [
33+
'mail_ux/static/src/core/common/**/*',
34+
],
35+
},
36+
'depends': [
37+
'mail',
38+
],
39+
'data': [
40+
],
41+
'demo': [
42+
],
43+
'test': [
44+
],
45+
'installable': True,
46+
'auto_install': False,
47+
'application': False,
48+
}

mail_ux/models/__init__.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
##############################################################################
2+
# For copyright and license notices, see __manifest__.py file in module root
3+
# directory
4+
##############################################################################
5+
from . import res_partner
6+
from . import mail_compose_message
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
from odoo import models, fields, api
2+
from datetime import datetime, timedelta
3+
from odoo.exceptions import UserError
4+
5+
class MailComposeMessage(models.TransientModel):
6+
_inherit = 'mail.compose.message'
7+
8+
def _action_send_mail(self, auto_commit=False):
9+
"""
10+
Heredado para incluir un retraso de 30 segundos al enviar mensajes.
11+
"""
12+
scheduled_date = datetime.now() + timedelta(seconds=30)
13+
result_mails_su, result_messages = super(MailComposeMessage, self)._action_send_mail(auto_commit=auto_commit)
14+
if self.composition_mode != 'mass_mail':
15+
for wizard in self:
16+
res_ids = wizard._evaluate_res_ids()
17+
for res_id in res_ids:
18+
self.env['mail.scheduled.message'].create({
19+
'attachment_ids': [(6, 0, wizard.attachment_ids.ids)],
20+
'author_id': self.env.user.partner_id.id,
21+
'body': wizard.body,
22+
'model': wizard.model,
23+
'res_id': res_id,
24+
'partner_ids': [(6, 0, wizard.partner_ids.ids)],
25+
'scheduled_date': scheduled_date,
26+
'subject': wizard.subject,
27+
'notification_parameters': '{}',
28+
})
29+
30+
return result_mails_su, result_messages

mail_ux/models/res_partner.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
##############################################################################
2+
# For copyright and license notices, see __manifest__.py file in module root
3+
# directory
4+
##############################################################################
5+
from odoo import models, fields, api
6+
from odoo.addons.mail.tools.discuss import Store
7+
from odoo.osv import expression
8+
9+
10+
class ResPartner(models.Model):
11+
_inherit = 'res.partner'
12+
13+
active = fields.Boolean(tracking=True)
14+
15+
@api.model
16+
def get_mention_suggestions(self, search, limit=100):
17+
"""
18+
Incluye solo usuarios internos al momento de mencionar usuarios en notas.
19+
"""
20+
internal_group = self.env.ref('base.group_user')
21+
internal_users = self.env['res.users'].search([
22+
('groups_id', 'in', internal_group.id),
23+
]).mapped('partner_id.id')
24+
domain = self._get_mention_suggestions_domain(search)
25+
domain = expression.AND([domain, [('id', 'in', internal_users)]])
26+
partners = self._search_mention_suggestions(domain, limit)
27+
return Store(partners).get_result()
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import { Composer } from "@mail/core/common/composer";
2+
import { patch } from "@web/core/utils/patch";
3+
import { useService } from "@web/core/utils/hooks";
4+
import { user } from "@web/core/user";
5+
6+
import {
7+
toRaw,
8+
} from "@odoo/owl";
9+
10+
patch(Composer.prototype, {
11+
12+
setup() {
13+
super.setup();
14+
this.actionService = useService("action");
15+
this.orm = useService("orm");
16+
},
17+
async sendScheduleMessage() {
18+
const composer = toRaw(this.props.composer);
19+
if (composer.message) {
20+
this.editMessage();
21+
return;
22+
}
23+
await this.processMessage(async (value) => {
24+
await this._sendScheduleMessage(value, this.postData, this.extraData);
25+
});
26+
},
27+
async _sendScheduleMessage(value, postData, extraData) {
28+
if (postData.isNote){
29+
return await this._sendMessage(value, postData, extraData);
30+
}
31+
32+
const thread = toRaw(this.props.composer.thread);
33+
const postThread = toRaw(this.thread);
34+
if (postThread.model === "discuss.channel") {
35+
// feature of (optimistic) temp message
36+
return await this._sendMessage(value, postData, extraData);
37+
} else {
38+
postData.attachments = postData.attachments ? [...postData.attachments] : []; // to not lose them on composer clear
39+
const { attachments, parentId, mentionedChannels, mentionedPartners } = postData;
40+
const body = value;
41+
const params = await this.store.getMessagePostParams({ body, postData, thread: thread });
42+
const scheduledDate = new Date();
43+
scheduledDate.setSeconds(scheduledDate.getSeconds() + 30);
44+
45+
const formattedScheduledDate = scheduledDate.toISOString().slice(0, 19).replace("T", " ");
46+
await this.orm.call("mail.scheduled.message", 'create', [
47+
{
48+
'attachment_ids': attachments.map(attachment => attachment.id),
49+
'author_id': user.partnerId,
50+
'body': body,
51+
'model': postThread.model,
52+
'res_id': postThread.id,
53+
'partner_ids': params.post_data.partner_ids || [],
54+
'scheduled_date': formattedScheduledDate,
55+
'notification_parameters': '{}',
56+
}])
57+
}
58+
}
59+
})
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?xml version="1.0" encoding="UTF-8" ?>
2+
<templates xml:space="preserve">
3+
<t t-name="mail.Composer.scheduleButton">
4+
<button class="o-mail-Composer-send btn"
5+
t-att-class="{
6+
'btn-primary btn-sm': extended,
7+
'btn-link p-1 rounded-pill': !extended,
8+
'me-2': env.inDiscussApp,
9+
'border-start-0': env.inDiscussApp and !props.composer.message,
10+
'border-0': props.composer.message,
11+
}"
12+
t-on-click="sendScheduleMessage"
13+
t-att-disabled="isSendButtonDisabled"
14+
t-att-aria-label="SEND_TEXT"
15+
>
16+
<t t-if="thread and thread.model !== 'discuss.channel'" t-out="SEND_TEXT"/>
17+
<t t-else=""><i class="fa fa-fw fa-paper-plane-o"/></t>
18+
</button>
19+
</t>
20+
21+
22+
<t t-inherit="mail.Composer.sendButton" t-inherit-mode="extension">
23+
<button position='attributes'>
24+
<attribute name="t-on-click">sendScheduleMessage</attribute>
25+
</button>
26+
</t>
27+
</templates>
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<odoo>
3+
4+
<record id="view_window_action_form" model="ir.ui.view">
5+
<field name="name">ir.actions.act_window.form</field>
6+
<field name="model">ir.actions.act_window</field>
7+
<field name="inherit_id" ref="base.view_window_action_form"/>
8+
<field name="arch" type="xml">
9+
<field name="name" position="before">
10+
<field name="binding_model_id" invisible="1"/>
11+
</field>
12+
<group position="before">
13+
<div class="d-flex align-item-end justify-content-end mt8">
14+
<button name="create_action" string="Add in the 'Action' menu" type="object"
15+
invisible="not res_model or binding_model_id"
16+
help="Display an option on related documents to open this action"/>
17+
<button name="unlink_action" string="Remove from the 'Action' menu" type="object"
18+
invisible="not binding_model_id"
19+
help="Remove the contextual action related this action"/>
20+
</div>
21+
</group>
22+
</field>
23+
</record>
24+
25+
</odoo>

0 commit comments

Comments
 (0)