Chris White
6 years ago
28 changed files with 130 additions and 227 deletions
-
2mail_activity/__init__.py
-
2mail_activity/__manifest__.py
-
124mail_activity/hooks.py
-
1mail_activity/models/__init__.py
-
28mail_activity/models/mail_activity.py
-
38mail_activity/models/mail_activity_mixin.py
-
2mail_activity/models/mail_activity_type.py
-
15mail_activity/models/mail_compose_message.py
-
2mail_activity/models/mail_message.py
-
7mail_activity/models/res_partner.py
-
2mail_activity/models/res_users.py
-
4mail_activity/static/src/less/systray.less
-
2mail_activity/static/src/xml/systray.xml
-
4mail_activity/tests/test_mail_activity.py
-
0mail_activity/views/crm_action_views.xml
-
2mail_activity/wizards/__init__.py
-
12mail_activity/wizards/mail_compose_message.py
-
0mail_activity_calendar/__manifest__.py
-
2mail_activity_crm/__manifest__.py
-
4mail_activity_crm/hooks.py
-
2mail_activity_crm/models/__init__.py
-
2mail_activity_crm/models/calendar_event.py
-
19mail_activity_crm/models/crm_activity_report.py
-
56mail_activity_crm/models/crm_activity_report_odoo_v10.py
-
8mail_activity_crm/models/crm_lead.py
-
2mail_activity_crm/models/mail_activity.py
-
11mail_activity_crm/views/crm_activity_report_view.xml
-
4mail_activity_crm/views/crm_lead_menu.xml
@ -1,4 +1,2 @@ |
|||
# -*- coding: utf-8 -*- |
|||
from . import models |
|||
from . import wizards |
|||
from .hooks import post_load_hook |
@ -1,124 +0,0 @@ |
|||
# Copyright 2018 Eficent Business and IT Consulting Services S.L. |
|||
# Copyright 2018 Odoo, S.A. |
|||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html). |
|||
|
|||
from openerp.addons.mail.wizard.mail_compose_message import MailComposer |
|||
|
|||
|
|||
def post_load_hook(): |
|||
""" |
|||
We need this hook only in v9 in order to be able to capture the subtype. |
|||
|
|||
""" |
|||
def new_send_mail(self, auto_commit=False): |
|||
|
|||
if 'subtype_id' not in self._fields: |
|||
return self.send_mail_original(auto_commit=auto_commit) |
|||
|
|||
""" Process the wizard content and proceed with sending the related |
|||
email(s), rendering any template patterns on the fly |
|||
if needed. """ |
|||
for wizard in self: |
|||
# Duplicate attachments linked to the email.template. |
|||
# Indeed, basic mail.compose.message wizard duplicates |
|||
# attachments in mass |
|||
# mailing mode. But in 'single post' mode, attachments of |
|||
# an email template |
|||
# also have to be duplicated to avoid changing their ownership. |
|||
if wizard.attachment_ids and \ |
|||
wizard.composition_mode != 'mass_mail' and \ |
|||
wizard.template_id: |
|||
new_attachment_ids = [] |
|||
for attachment in wizard.attachment_ids: |
|||
if attachment in wizard.template_id.attachment_ids: |
|||
new_attachment_ids.append(attachment.copy( |
|||
{'res_model': 'mail.compose.message', |
|||
'res_id': wizard.id}).id) |
|||
else: |
|||
new_attachment_ids.append(attachment.id) |
|||
wizard.write({'attachment_ids': [(6, 0, |
|||
new_attachment_ids)]}) |
|||
|
|||
# Mass Mailing |
|||
mass_mode = wizard.composition_mode in ('mass_mail', 'mass_post') |
|||
|
|||
Mail = self.env['mail.mail'] |
|||
ActiveModel = self.env[ |
|||
wizard.model if wizard.model else 'mail.thread'] |
|||
if wizard.template_id: |
|||
# template user_signature is added when generating body_html |
|||
# mass mailing: use template auto_delete value -> note, |
|||
# for emails mass mailing only |
|||
Mail = Mail.with_context(mail_notify_user_signature=False) |
|||
ActiveModel = ActiveModel.with_context( |
|||
mail_notify_user_signature=False, |
|||
mail_auto_delete=wizard.template_id.auto_delete) |
|||
if not hasattr(ActiveModel, 'message_post'): |
|||
ActiveModel = self.env['mail.thread'].with_context( |
|||
thread_model=wizard.model) |
|||
if wizard.composition_mode == 'mass_post': |
|||
# do not send emails directly but use the queue instead |
|||
# add context key to avoid subscribing the author |
|||
ActiveModel = ActiveModel.with_context( |
|||
mail_notify_force_send=False, |
|||
mail_create_nosubscribe=True) |
|||
# wizard works in batch mode: [res_id] or |
|||
# active_ids or active_domain |
|||
if mass_mode and wizard.use_active_domain and wizard.model: |
|||
res_ids = self.env[wizard.model].search( |
|||
eval(wizard.active_domain)).ids |
|||
elif mass_mode and wizard.model and self._context.get( |
|||
'active_ids'): |
|||
res_ids = self._context['active_ids'] |
|||
else: |
|||
res_ids = [wizard.res_id] |
|||
|
|||
batch_size = int(self.env['ir.config_parameter'].sudo().get_param( |
|||
'mail.batch_size')) or self._batch_size |
|||
sliced_res_ids = [res_ids[i:i + batch_size] for i in |
|||
range(0, len(res_ids), batch_size)] |
|||
|
|||
# ---- START OF PATCH |
|||
if wizard.composition_mode == 'mass_mail' or wizard.is_log or ( |
|||
wizard.composition_mode == 'mass_post' |
|||
and not wizard.notify): # log a note: subtype is False |
|||
subtype_id = False |
|||
elif wizard.subtype_id: |
|||
subtype_id = wizard.subtype_id |
|||
else: |
|||
subtype_id = self.sudo().env.ref('mail.mt_comment', |
|||
raise_if_not_found=False) |
|||
if subtype_id: |
|||
external_subtype = subtype_id.get_external_id() |
|||
if external_subtype: |
|||
subtype = external_subtype[subtype_id.id] |
|||
else: |
|||
subtype = 'mail.mt_comment' |
|||
# ---- END OF PATCH |
|||
|
|||
for res_ids in sliced_res_ids: |
|||
batch_mails = Mail |
|||
all_mail_values = wizard.get_mail_values(res_ids) |
|||
for res_id, mail_values in all_mail_values.iteritems(): |
|||
if wizard.composition_mode == 'mass_mail': |
|||
batch_mails |= Mail.create(mail_values) |
|||
else: |
|||
# subtype = 'mail.mt_comment' -> Removed |
|||
if wizard.is_log or ( |
|||
wizard.composition_mode == 'mass_post' |
|||
and not wizard.notify): # log a note: |
|||
# subtype is False |
|||
subtype = False |
|||
ActiveModel.browse(res_id).message_post( |
|||
message_type='comment', subtype=subtype, |
|||
**mail_values) |
|||
|
|||
if wizard.composition_mode == 'mass_mail': |
|||
batch_mails.send(auto_commit=auto_commit) |
|||
|
|||
return {'type': 'ir.actions.act_window_close'} |
|||
|
|||
if not hasattr(MailComposer, 'send_mail_original'): |
|||
MailComposer.send_mail_original = MailComposer.send_mail |
|||
|
|||
MailComposer.send_mail = new_send_mail |
@ -0,0 +1,15 @@ |
|||
from odoo import api, fields, models |
|||
|
|||
|
|||
class MailComposeMessage(models.TransientModel): |
|||
_inherit = 'mail.compose.message' |
|||
|
|||
@api.multi |
|||
def get_mail_values(self, res_ids): |
|||
"""Generate the values that will be used by send_mail to create mail_messages |
|||
or mail_mails. """ |
|||
results = super(MailComposeMessage, self).get_mail_values(res_ids) |
|||
|
|||
for res_id in res_ids: |
|||
results[res_id]['mail_activity_type_id'] = self.mail_activity_type_id.id |
|||
return results |
@ -1,2 +0,0 @@ |
|||
# -*- coding: utf-8 -*- |
|||
from . import mail_compose_message |
@ -1,12 +0,0 @@ |
|||
# -*- coding: utf-8 -*- |
|||
from openerp import fields, models |
|||
|
|||
|
|||
class MailComposer(models.TransientModel): |
|||
|
|||
_inherit = 'mail.compose.message' |
|||
|
|||
# This field is already in v10 onwards. |
|||
subtype_id = fields.Many2one( |
|||
default=lambda self: self.sudo().env.ref('mail.mt_comment', |
|||
raise_if_not_found=False).id) |
@ -0,0 +1,19 @@ |
|||
from odoo import api, fields, models |
|||
|
|||
|
|||
class CrmActivityReport(models.Model): |
|||
_inherit = 'crm.activity.report' |
|||
|
|||
mail_activity_type_id = fields.Many2one('mail.activity.type', 'Activity Type', readonly=True) |
|||
|
|||
def _select(self): |
|||
select = super(CrmActivityReport, self)._select() |
|||
return select + """ |
|||
, m.mail_activity_type_id |
|||
""" |
|||
|
|||
def _where(self): |
|||
where = super(CrmActivityReport, self)._where() |
|||
return where + """ |
|||
-- AND m.mail_activity_type_id IS NOT NULL |
|||
""" |
@ -0,0 +1,56 @@ |
|||
from odoo import tools, api, fields, models |
|||
|
|||
# Copy Odoo's implementation in v12 back to v10 so that we have useful hooks to add what we need to later on. |
|||
|
|||
|
|||
class CrmActivityReportOdoo(models.Model): |
|||
_inherit = 'crm.activity.report' |
|||
|
|||
def _select(self): |
|||
return """ |
|||
SELECT |
|||
m.id, |
|||
m.subtype_id, |
|||
m.author_id, |
|||
m.date, |
|||
m.subject, |
|||
l.id as lead_id, |
|||
l.user_id, |
|||
l.team_id, |
|||
l.country_id, |
|||
l.company_id, |
|||
l.stage_id, |
|||
l.partner_id, |
|||
l.type as lead_type, |
|||
l.active, |
|||
l.probability |
|||
""" |
|||
|
|||
def _from(self): |
|||
return """ |
|||
FROM mail_message AS m |
|||
""" |
|||
|
|||
def _join(self): |
|||
return """ |
|||
JOIN crm_lead AS l ON m.res_id = l.id |
|||
""" |
|||
|
|||
def _where(self): |
|||
return """ |
|||
WHERE |
|||
m.model = 'crm.lead' |
|||
""" |
|||
|
|||
@api.model_cr |
|||
def init(self): |
|||
tools.drop_view_if_exists(self._cr, self._table) |
|||
self._cr.execute(""" |
|||
CREATE OR REPLACE VIEW %s AS ( |
|||
%s |
|||
%s |
|||
%s |
|||
%s |
|||
) |
|||
""" % (self._table, self._select(), self._from(), self._join(), self._where()) |
|||
) |
@ -1,11 +0,0 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<openerp> |
|||
<data> |
|||
<!-- hide --> |
|||
<record id="crm.crm_activity_report_menu" model="ir.ui.menu"> |
|||
<field name="groups_id" eval="[(6, 0, [ref('base.group_no_one')])]"/> |
|||
<field name="name">Activities (obsolete)</field> |
|||
</record> |
|||
|
|||
</data> |
|||
</openerp> |
Write
Preview
Loading…
Cancel
Save
Reference in new issue