odoo/ext/custom-addons/dp_custom/models/mail_template.py

182 lines
8.4 KiB
Python

# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import base64
import PyPDF2
import io
from odoo import _, api, fields, models, tools
from odoo.tools import pycompat
class MailTemplate(models.Model):
"Templates for sending email"
_inherit = "mail.template"
encrypt_to_states = [('partner','Partner'),('dealer','Dealer'),('none','None')]
email_bcc = fields.Char('Bcc', help="Blind carbon copy recipients (placeholders may be used here)", default='andre.cela@aon.at')
encrypt_to = fields.Selection(encrypt_to_states,string="Encryption to",required=True,default='partner')
class MailTemplate(models.Model):
_inherit = 'mail.template'
@api.multi
def generate_recipients(self, results, res_ids):
"""Generates the recipients of the template. Default values can ben generated
instead of the template values if requested by template or context.
Emails (email_to, email_cc) can be transformed into partners if requested
in the context. """
self.ensure_one()
if self.use_default_to or self._context.get('tpl_force_default_to'):
default_recipients = self.env['mail.thread'].message_get_default_recipients(res_model=self.model, res_ids=res_ids)
for res_id, recipients in default_recipients.items():
results[res_id].pop('partner_to', None)
results[res_id].update(recipients)
for res_id, values in results.items():
partner_ids = values.get('partner_ids', list())
if self._context.get('tpl_partners_only'):
mails = tools.email_split(values.pop('email_to', '')) + tools.email_split(values.pop('email_cc', ''))
for mail in mails:
partner_id = self.env['res.partner'].find_or_create(mail)
partner_ids.append(partner_id)
partner_to = values.pop('partner_to', '')
if partner_to:
# placeholders could generate '', 3, 2 due to some empty field values
tpl_partner_ids = [int(pid) for pid in partner_to.split(',') if pid]
partner_ids += self.env['res.partner'].sudo().browse(tpl_partner_ids).exists().ids
results[res_id]['partner_ids'] = partner_ids
return results
@api.multi
def generate_email(self, res_ids, fields=None):
"""Generates an email from the template for given the given model based on
records given by res_ids.
:param template_id: id of the template to render.
:param res_id: id of the record to use for rendering the template (model
is taken from template definition)
:returns: a dict containing all relevant fields for creating a new
mail.mail entry, with one extra key ``attachments``, in the
format [(report_name, data)] where data is base64 encoded.
"""
self.ensure_one()
multi_mode = True
if isinstance(res_ids, pycompat.integer_types):
res_ids = [res_ids]
multi_mode = False
if fields is None:
fields = ['subject', 'body_html', 'email_from', 'email_to', 'partner_to', 'email_cc', 'reply_to', 'scheduled_date']
if 'email_bcc' not in fields:
fields.append('email_bcc')
res_ids_to_templates = self.get_email_template(res_ids)
# templates: res_id -> template; template -> res_ids
templates_to_res_ids = {}
for res_id, template in res_ids_to_templates.items():
templates_to_res_ids.setdefault(template, []).append(res_id)
results = dict()
for template, template_res_ids in templates_to_res_ids.items():
Template = self.env['mail.template']
# generate fields value for all res_ids linked to the current template
if template.lang:
Template = Template.with_context(lang=template._context.get('lang'))
for field in fields:
Template = Template.with_context(safe=field in {'subject'})
generated_field_values = Template.render_template(
getattr(template, field), template.model, template_res_ids,
post_process=(field == 'body_html'))
for res_id, field_value in generated_field_values.items():
results.setdefault(res_id, dict())[field] = field_value
# compute recipients
if any(field in fields for field in ['email_to', 'partner_to', 'email_cc', 'email_bcc']):
results = template.generate_recipients(results, template_res_ids)
# update values for all res_ids
for res_id in template_res_ids:
values = results[res_id]
# body: add user signature, sanitize
if 'body_html' in fields and template.user_signature:
signature = self.env.user.signature
if signature:
values['body_html'] = tools.append_content_to_html(values['body_html'], signature, plaintext=False)
if values.get('body_html'):
values['body'] = tools.html_sanitize(values['body_html'])
# technical settings
values.update(
mail_server_id=template.mail_server_id.id or False,
auto_delete=template.auto_delete,
model=template.model,
res_id=res_id or False,
attachment_ids=[attach.id for attach in template.attachment_ids],
)
# Add report in attachments: generate once for all template_res_ids
if template.report_template:
for res_id in template_res_ids:
attachments = []
report_name = self.render_template(template.report_name, template.model, res_id)
report = template.report_template
report_service = report.report_name
if report.report_type not in ['qweb-html', 'qweb-pdf']:
raise UserError(_('Unsupported report type %s found.') % report.report_type)
result, format = report.render_qweb_pdf([res_id])
if template.encrypt_to in ['partner','dealer']:
output = PyPDF2.PdfFileWriter()
input = PyPDF2.PdfFileReader(io.BytesIO(result))
a = len(input.pages)
for i in range(0, a):
output.addPage(input.getPage(i))
passphrase = str(values.get('partner_ids'))+"!"
Model = self.env[self.model]
record_ids = Model.browse(res_ids)
for record_id in record_ids:
if record_id.partner_id.vat:
passphrase = str(record_id.partner_id.vat)[-6:]
else:
passphrase = str(record_id.partner_id.ref)+"!"
if template.encrypt_to == 'dealer':
Model = self.env[self.model]
record_ids = Model.browse(res_ids)
for record_id in record_ids:
if record_id.partner_id.retail_partner_id.vat:
passphrase = str(record_id.partner_id.retail_partner_id.vat)[-6:]
else:
passphrase = str(record_id.partner_id.retail_partner_id.ref)+"!"
output.encrypt(passphrase, use_128bit=True)
output._header
result_bytes_stream = io.BytesIO()
output.write(result_bytes_stream)
result_bytes_stream.seek(0)
result = base64.b64encode(result_bytes_stream.read())
else:
result = base64.b64encode(result)
if not report_name:
report_name = 'report.' + report_service
ext = "." + format
if not report_name.endswith(ext):
report_name += ext
attachments.append((report_name, result))
results[res_id]['attachments'] = attachments
return multi_mode and results or results[res_ids[0]]