[MERGE][REF] survey: break survey composer inherit on mail composer
Purpose of this merge is to clean survey composer model. It currently inherits from mail.compose.message which also inherits from mail.message. That means a lot of fields and behavior coming from both models are present on the survey composer. Most of them are not necessary as * send_mail method of mail composer is overriden and super is not called. Nothing from the complex behavior of mail.compose.message is used; * templates are just basically supported in survey, notably mass mailing or mass posting mode are not used; * methods from mail.message should not be available on survey composer; * most m2m fields coming from mail.message and composer have no use here; In this merge we simply add the required fields and template behavior on the survey composer and remove inheritance on mail.compose.message. In this merge we also rename survey.mail.compose.message to survey.invite as it simplifies code and is easier to understand. This commit is linked to task ID 1909804. closes odoo/odoo#28783
This commit is contained in:
@@ -31,7 +31,7 @@ sent mails with personal token for the invitation of the survey.
|
||||
'views/survey_question_views.xml',
|
||||
'views/survey_page_views.xml',
|
||||
'views/survey_templates.xml',
|
||||
'wizard/survey_mail_compose_message_views.xml',
|
||||
'wizard/survey_invite_views.xml',
|
||||
],
|
||||
'demo': [
|
||||
'data/survey_demo_user.xml',
|
||||
|
||||
@@ -302,7 +302,7 @@ class Survey(models.Model):
|
||||
'type': 'ir.actions.act_window',
|
||||
'view_type': 'form',
|
||||
'view_mode': 'form',
|
||||
'res_model': 'survey.mail.compose.message',
|
||||
'res_model': 'survey.invite',
|
||||
'target': 'new',
|
||||
'context': local_context,
|
||||
}
|
||||
|
||||
@@ -132,7 +132,7 @@ class TestSurvey(TransactionCase):
|
||||
'type': 'ir.actions.act_window',
|
||||
'view_type': 'form',
|
||||
'view_mode': 'form',
|
||||
'res_model': 'survey.mail.compose.message',
|
||||
'res_model': 'survey.invite',
|
||||
'target': 'new',
|
||||
'context': ctx,
|
||||
})
|
||||
@@ -150,15 +150,15 @@ class TestSurvey(TransactionCase):
|
||||
def test_07_survey_email_message(self):
|
||||
# Case-1: Executing send_mail with correct data.
|
||||
partner = self.env['res.partner'].create({'name': 'Marie De Cock', 'email': 'marie.de.cock@gmail.com'})
|
||||
survey_mail_message = self.env['survey.mail.compose.message'].sudo(self.survey_manager).create({
|
||||
survey_mail_message = self.env['survey.invite'].sudo(self.survey_manager).create({
|
||||
'survey_id': self.survey1.id, 'public': 'email_public_link', 'body': '__URL__', 'partner_ids': [(4, partner.id)]})
|
||||
survey_mail_message.send_mail()
|
||||
|
||||
# Case-2: Executing send_mail with incorrect data.
|
||||
mail_messages = [
|
||||
self.env['survey.mail.compose.message'].sudo(self.survey_manager).create({ # Mail Message without __URL__ in body.
|
||||
self.env['survey.invite'].sudo(self.survey_manager).create({ # Mail Message without __URL__ in body.
|
||||
'survey_id': self.survey1.id, 'public': 'email_public_link'}),
|
||||
self.env['survey.mail.compose.message'].sudo(self.survey_manager).create({ # Mail Message without recipents.
|
||||
self.env['survey.invite'].sudo(self.survey_manager).create({ # Mail Message without recipents.
|
||||
'survey_id': self.survey1.id, 'public': 'email_public_link', 'body': "__URL__"})]
|
||||
for message in mail_messages:
|
||||
self.assertRaises(UserError, message.send_mail)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from . import survey_mail_compose_message
|
||||
from . import survey_invite
|
||||
|
||||
+80
-11
@@ -5,6 +5,7 @@ import logging
|
||||
import re
|
||||
import uuid
|
||||
|
||||
from email.utils import formataddr
|
||||
from werkzeug import urls
|
||||
|
||||
from odoo import api, fields, models, _
|
||||
@@ -17,16 +18,47 @@ emails_split = re.compile(r"[;,\n\r]+")
|
||||
email_validator = re.compile(r"[^@]+@[^@]+\.[^@]+")
|
||||
|
||||
|
||||
class SurveyMailComposeMessage(models.TransientModel):
|
||||
_name = 'survey.mail.compose.message'
|
||||
_inherit = 'mail.compose.message'
|
||||
_description = 'Email composition wizard for Survey'
|
||||
class SurveyInvite(models.TransientModel):
|
||||
_name = 'survey.invite'
|
||||
_description = 'Survey Invitation Wizard'
|
||||
|
||||
def default_survey_id(self):
|
||||
context = self.env.context
|
||||
if context.get('model') == 'survey.survey':
|
||||
return context.get('res_id')
|
||||
|
||||
@api.model
|
||||
def _get_default_from(self):
|
||||
if self.env.user.email:
|
||||
return formataddr((self.env.user.name, self.env.user.email))
|
||||
raise UserError(_("Unable to post message, please configure the sender's email address."))
|
||||
|
||||
@api.model
|
||||
def _get_default_author(self):
|
||||
return self.env.user.partner_id
|
||||
|
||||
# composer content
|
||||
subject = fields.Char('Subject')
|
||||
body = fields.Html('Contents', default='', sanitize_style=True)
|
||||
attachment_ids = fields.Many2many(
|
||||
'ir.attachment', 'survey_mail_compose_message_ir_attachments_rel', 'wizard_id', 'attachment_id',
|
||||
string='Attachments')
|
||||
template_id = fields.Many2one(
|
||||
'mail.template', 'Use template', index=True,
|
||||
domain="[('model', '=', 'survey.survey')]")
|
||||
# origin
|
||||
email_from = fields.Char('From', default=_get_default_from, help="Email address of the sender.")
|
||||
author_id = fields.Many2one(
|
||||
'res.partner', 'Author', index=True,
|
||||
ondelete='set null', default=_get_default_author,
|
||||
help="Author of the message.")
|
||||
# recipients
|
||||
partner_ids = fields.Many2many('res.partner', 'survey_mail_compose_message_res_partner_rel', 'wizard_id', 'partner_id', string='Existing contacts')
|
||||
multi_email = fields.Text(string='List of emails', help="This list of emails of recipients will not be converted in contacts.\
|
||||
Emails must be separated by commas, semicolons or newline.")
|
||||
# technical info
|
||||
mail_server_id = fields.Many2one('ir.mail_server', 'Outgoing mail server')
|
||||
# survey
|
||||
survey_id = fields.Many2one('survey.survey', string='Survey', default=default_survey_id, required=True)
|
||||
public = fields.Selection([('public_link', 'Share the public web link to your audience.'),
|
||||
('email_public_link', 'Send by email the public web link to your audience.'),
|
||||
@@ -34,10 +66,6 @@ class SurveyMailComposeMessage(models.TransientModel):
|
||||
string='Share options', default='public_link', required=True)
|
||||
public_url = fields.Char(compute="_compute_survey_url", string="Public url")
|
||||
public_url_html = fields.Char(compute="_compute_survey_url", string="Public HTML web link")
|
||||
partner_ids = fields.Many2many('res.partner', 'survey_mail_compose_message_res_partner_rel', 'wizard_id', 'partner_id', string='Existing contacts')
|
||||
attachment_ids = fields.Many2many('ir.attachment', 'survey_mail_compose_message_ir_attachments_rel', 'wizard_id', 'attachment_id', string='Attachments')
|
||||
multi_email = fields.Text(string='List of emails', help="This list of emails of recipients will not be converted in contacts.\
|
||||
Emails must be separated by commas, semicolons or newline.")
|
||||
date_deadline = fields.Date(string="Deadline to which the invitation to respond is valid",
|
||||
help="Deadline to which the invitation to respond for this survey is valid. If the field is empty,\
|
||||
the invitation is still valid.")
|
||||
@@ -50,7 +78,7 @@ class SurveyMailComposeMessage(models.TransientModel):
|
||||
|
||||
@api.model
|
||||
def default_get(self, fields):
|
||||
res = super(SurveyMailComposeMessage, self).default_get(fields)
|
||||
res = super(SurveyInvite, self).default_get(fields)
|
||||
context = self.env.context
|
||||
if context.get('active_model') == 'res.partner' and context.get('active_ids'):
|
||||
res.update({'partner_ids': context['active_ids']})
|
||||
@@ -74,6 +102,49 @@ class SurveyMailComposeMessage(models.TransientModel):
|
||||
emails_checked.sort()
|
||||
self.multi_email = '\n'.join(emails_checked)
|
||||
|
||||
@api.onchange('template_id', 'survey_id')
|
||||
def _onchange_template_id(self):
|
||||
""" UPDATE ME """
|
||||
to_render_fields = [
|
||||
'subject', 'body_html',
|
||||
'email_from', 'reply_to',
|
||||
'partner_to', 'email_to', 'email_cc',
|
||||
'attachment_ids',
|
||||
'mail_server_id'
|
||||
]
|
||||
returned_fields = to_render_fields + ['partner_ids', 'attachments']
|
||||
for wizard in self:
|
||||
if wizard.template_id:
|
||||
values = {}
|
||||
|
||||
template_values = wizard.template_id.generate_email([wizard.survey_id.id], fields=to_render_fields)[wizard.survey_id.id]
|
||||
values = dict((field, template_values[field]) for field in returned_fields if template_values.get(field))
|
||||
values['body'] = values.pop('body_html', '')
|
||||
|
||||
# transform attachments into attachment_ids; not attached to the document because this will
|
||||
# be done further in the posting process, allowing to clean database if email not send
|
||||
Attachment = self.env['ir.attachment']
|
||||
for attach_fname, attach_datas in values.pop('attachments', []):
|
||||
data_attach = {
|
||||
'name': attach_fname,
|
||||
'datas': attach_datas,
|
||||
'datas_fname': attach_fname,
|
||||
'res_model': 'mail.compose.message', # TDE CHECKME
|
||||
'res_id': 0,
|
||||
'type': 'binary', # override default_type from context, possibly meant for another model!
|
||||
}
|
||||
values.setdefault('attachment_ids', list()).append(Attachment.create(data_attach).id)
|
||||
else:
|
||||
default_values = self.default_get(returned_fields)
|
||||
values = dict((key, default_values[key]) for key in returned_fields if key in default_values)
|
||||
|
||||
# This onchange should return command instead of ids for x2many field.
|
||||
# ORM handle the assignation of command list on new onchange (api.v8),
|
||||
# this force the complete replacement of x2many field with
|
||||
# command and is compatible with onchange api.v7
|
||||
values = self._convert_to_write(values)
|
||||
wizard.update(values)
|
||||
|
||||
#------------------------------------------------------
|
||||
# Wizard validation and send
|
||||
#------------------------------------------------------
|
||||
@@ -183,8 +254,6 @@ class SurveyMailComposeMessage(models.TransientModel):
|
||||
partner_list.append({'id': partner.id, 'email': partner.email})
|
||||
|
||||
if not len(emails_list) and not len(partner_list):
|
||||
if wizard.model == 'res.partner' and wizard.res_id:
|
||||
return False
|
||||
raise UserError(_("Please enter at least one valid recipient."))
|
||||
|
||||
for email in emails_list:
|
||||
+3
-10
@@ -1,19 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<data>
|
||||
|
||||
<!-- Replace the default mass-mailing wizard in base with the composition wizard -->
|
||||
|
||||
<!-- Composition form (context['survey_resent_token'], if True, hide share option, emails list and partner_ids) -->
|
||||
<record model="ir.ui.view" id="survey_email_compose_message">
|
||||
<field name="name">survey.mail.compose.message.form</field>
|
||||
<field name="model">survey.mail.compose.message</field>
|
||||
<record model="ir.ui.view" id="survey_invite_view_form">
|
||||
<field name="name">survey.invite.view.form</field>
|
||||
<field name="model">survey.invite</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Compose Email">
|
||||
<field name="composition_mode" invisible="1"/>
|
||||
<field name="model" invisible="1"/>
|
||||
<field name="res_id" invisible="1"/>
|
||||
<field name="parent_id" invisible="1"/>
|
||||
<group col="2">
|
||||
<field name="survey_id" readonly="context.get('default_survey_id')"/>
|
||||
<field name="public" widget="radio" invisible="context.get('survey_resent_token')" />
|
||||
Reference in New Issue
Block a user