[REF] survey: refactor template use on invite wizard
Purpose of this merge is to remove the ugly __URL__ hack of survey templates. It is solved by making template rendered on user_input model. This means each invitation recipient will received its own rendered mail. Small jinja code allows therefore to include the url in a clean odoo-style way. Subject and body in survey invite wizard are not rendered anymore. It means jinja could be displayed. This is necessary as this wizard will work in batch mode, rendering the body on each recipient. This commit is linked to task ID 1911586 and PR #28986.
This commit is contained in:
@@ -1,22 +1,23 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<data noupdate="1">
|
||||
<record id="email_template_survey" model="mail.template">
|
||||
<record id="mail_template_user_input_invite" model="mail.template">
|
||||
<field name="name">Survey: Send by email</field>
|
||||
<field name="model_id" ref="model_survey_survey" />
|
||||
<field name="subject">${object.title}: Survey</field>
|
||||
<field name="model_id" ref="model_survey_user_input" />
|
||||
<field name="subject">Participate to ${object.survey_id.title} survey</field>
|
||||
<field name="body_html" type="html">
|
||||
<div style="margin: 0px; padding: 0px; font-size: 13px;">
|
||||
<p style="margin: 0px; padding: 0px; font-size: 13px;">
|
||||
Hello<br /><br />
|
||||
We are conducting a survey, and your response would be appreciated.
|
||||
Dear ${object.partner_id.name or 'participant'}<br/><br/>
|
||||
We are conducting a survey and your response would be appreciated.
|
||||
<div style="margin: 16px 0px 16px 0px;">
|
||||
<a href="__URL__"
|
||||
<a href="${('%s?token=%s' % (object.survey_id.public_url, object.token)) | safe}"
|
||||
style="background-color: #875A7B; padding: 8px 16px 8px 16px; text-decoration: none; color: #fff; border-radius: 5px; font-size:13px;">
|
||||
Start Survey
|
||||
</a>
|
||||
</div>
|
||||
Thanks for your participation!
|
||||
Please answer the appraisal for ${format_date(object.deadline)}.<br/><br/>
|
||||
Thank you for your participation.
|
||||
</p>
|
||||
</div>
|
||||
</field>
|
||||
|
||||
@@ -341,7 +341,7 @@ class Survey(models.Model):
|
||||
if self.stage_id.closed:
|
||||
raise UserError(_("You cannot send invitations for closed surveys."))
|
||||
|
||||
template = self.env.ref('survey.email_template_survey', raise_if_not_found=False)
|
||||
template = self.env.ref('survey.mail_template_user_input_invite', raise_if_not_found=False)
|
||||
|
||||
local_context = dict(
|
||||
self.env.context,
|
||||
|
||||
@@ -36,7 +36,7 @@ class SurveyInvite(models.TransientModel):
|
||||
string='Attachments')
|
||||
template_id = fields.Many2one(
|
||||
'mail.template', 'Use template', index=True,
|
||||
domain="[('model', '=', 'survey.survey')]")
|
||||
domain="[('model', '=', 'survey.user_input')]")
|
||||
# origin
|
||||
email_from = fields.Char('From', default=_get_default_from, help="Email address of the sender.")
|
||||
author_id = fields.Many2one(
|
||||
@@ -108,48 +108,22 @@ class SurveyInvite(models.TransientModel):
|
||||
_('The following recipients have no user account: %s. You should create user accounts for them or allow external signup in configuration.' %
|
||||
(','.join(invalid_partners.mapped('name')))))
|
||||
|
||||
@api.onchange('template_id', 'survey_id')
|
||||
@api.onchange('template_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 = {}
|
||||
if self.template_id:
|
||||
self.subject = self.template_id.subject
|
||||
self.body = self.template_id.body_html
|
||||
|
||||
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)
|
||||
@api.model
|
||||
def create(self, values):
|
||||
if values.get('template_id') and not (values.get('body') or values.get('subject')):
|
||||
template = self.env['mail.template'].browse(values['template_id'])
|
||||
if not values.get('subject'):
|
||||
values['subject'] = template.subject
|
||||
if not values.get('body'):
|
||||
values['body'] = template.body_html
|
||||
return super(SurveyInvite, self).create(values)
|
||||
|
||||
#------------------------------------------------------
|
||||
# Wizard validation and send
|
||||
@@ -182,24 +156,29 @@ class SurveyInvite(models.TransientModel):
|
||||
answers |= existing_answers
|
||||
|
||||
for new_partner in partners - partners_done:
|
||||
answers |= self.survey_id._create_answer(partner=new_partner, deadline=self.deadline)
|
||||
answers |= self.survey_id._create_answer(partner=new_partner, **self._get_answers_values())
|
||||
for new_email in [email for email in emails if email not in emails_done]:
|
||||
answers |= self.survey_id._create_answer(email=new_email, deadline=self.deadline)
|
||||
answers |= self.survey_id._create_answer(email=new_email, **self._get_answers_values())
|
||||
|
||||
return answers
|
||||
|
||||
def _get_answers_values(self):
|
||||
return {
|
||||
'deadline': self.deadline,
|
||||
}
|
||||
|
||||
def _send_mail(self, answer):
|
||||
""" Create mail specific for recipient containing notably its access token """
|
||||
url = '%s?token=%s' % (self.survey_id.public_url, answer.token)
|
||||
|
||||
subject = self.env['mail.template']._render_template(self.subject, 'survey.user_input', answer.id, post_process=True)
|
||||
body = self.env['mail.template']._render_template(self.body, 'survey.user_input', answer.id, post_process=True)
|
||||
# post the message
|
||||
mail_values = {
|
||||
'email_from': self.email_from,
|
||||
'author_id': self.author_id.id,
|
||||
'model': None,
|
||||
'res_id': None,
|
||||
'subject': self.subject,
|
||||
'body_html': self.body.replace("__URL__", url),
|
||||
'subject': subject,
|
||||
'body_html': body,
|
||||
'attachment_ids': [(4, att.id) for att in self.attachment_ids],
|
||||
'auto_delete': True,
|
||||
}
|
||||
@@ -233,11 +212,6 @@ class SurveyInvite(models.TransientModel):
|
||||
self.ensure_one()
|
||||
Partner = self.env['res.partner']
|
||||
|
||||
# check if __URL__ is in the text
|
||||
if self.body.find("__URL__") < 0:
|
||||
raise UserError(_("The content of the text don't contain '__URL__'. \
|
||||
__URL__ is automaticaly converted into the special url of the survey."))
|
||||
|
||||
# compute partners and emails, try to find partners for given emails
|
||||
valid_partners = self.partner_ids
|
||||
valid_emails = []
|
||||
|
||||
Reference in New Issue
Block a user