208 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			Python
		
	
	
			
		
		
	
	
			208 lines
		
	
	
		
			10 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 = []
 | |
| 
 | |
|                     res_partner = self.env['res.partner'].browse(values.get('partner_ids'))
 | |
| 
 | |
|                     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
 | |
| 
 | |
|                     if not self.env.context.get('attach_ubl_xml_file'):
 | |
|                         return results
 | |
|                     for res_id, template in self.get_email_template(res_ids).items():
 | |
|                         invoice = self.env['account.invoice'].browse(res_id)
 | |
|                         version = invoice.get_ubl_version()
 | |
|                         ubl_filename = invoice.get_ubl_filename(version=version)
 | |
|                         ubl_attachments = self.env['ir.attachment'].search([
 | |
|                             ('res_model', '=', 'account.invoice'),
 | |
|                             ('res_id', '=', res_id),
 | |
|                             ('datas_fname', '=', ubl_filename)
 | |
|                         ], order='create_date desc', limit=1)
 | |
|                         if not ubl_attachments:
 | |
|                             ubl_attachments = invoice._generate_email_ubl_attachment()
 | |
|                         if len(ubl_attachments) == 1 and template.report_name:
 | |
|                             report_name = self.render_template(
 | |
|                                 template.report_name, template.model, res_id)
 | |
|                             ext = '.xml'
 | |
|                             if not report_name.endswith(ext):
 | |
|                                 report_name += ext
 | |
|                             attachments = [(report_name, ubl_attachments.datas)]
 | |
|                         else:
 | |
|                             attachments = [(a.name, a.datas) for a in ubl_attachments]
 | |
|                         results[res_id]['attachments'] += attachments
 | |
| 
 | |
|         return multi_mode and results or results[res_ids[0]]
 | |
| 
 |