def send_get_mail_body(self, partner=None): """ Override to add the tracking URL to the body and to add Statistic_id in shorted urls """ # TDE: temporary addition (mail was parameter) due to semi-new-API self.ensure_one() body = super(MailMail, self).send_get_mail_body(partner=partner) links_blacklist = ['/unsubscribe_from_list'] if self.mailing_id and body and self.statistics_ids: for match in re.findall(URL_REGEX, self.body_html): href = match[0] url = match[1] if not [s for s in links_blacklist if s in href]: new_href = href.replace(url, url + '/m/' + str(self.statistics_ids[0].id)) body = body.replace(href, new_href) # prepend <base> tag for images using absolute urls domain = self.env["ir.config_parameter"].get_param("web.base.url") base = "<base href='%s'>" % domain body = tools.append_content_to_html(base, body, plaintext=False, container_tag='div') # resolve relative image url to absolute for outlook.com def _sub_relative2absolute(match): return match.group(1) + urlparse.urljoin(domain, match.group(2)) body = re.sub('(<img(?=\s)[^>]*\ssrc=")(/[^/][^"]+)', _sub_relative2absolute, body) body = re.sub(r'(<[^>]+\bstyle="[^"]+\burl\(\'?)(/[^/\'][^\'")]+)', _sub_relative2absolute, body) # generate tracking URL if self.statistics_ids: tracking_url = self._get_tracking_url(partner) if tracking_url: body = tools.append_content_to_html(body, tracking_url, plaintext=False, container_tag='div') return body
def reply_mail(self): ctx = {} signature = self.env['res.users'].browse(self._uid).signature or '' body_html = tools.append_content_to_html('', signature, plaintext=False) body_html = tools.append_content_to_html(body_html, self.body_html, plaintext=False) if self.email_from: ctx.update({ 'default_email_to': self.email_from, 'default_subject': "Re: " + self.subject or "/", 'default_body_html': body_html, 'default_references': self.message_id, 'form_view_ref': 'email_management.pop_up_compose_mail', }) return { 'name': 'Reply Email', 'view_mode': 'form', 'view_type': 'form', 'context': ctx, 'res_model': 'mail.inbox', 'type': 'ir.actions.act_window', 'target': 'new', 'res_id': False, }
def _send_prepare_body(self): """ Override to add the tracking URL to the body and to add trace ID in shortened urls """ # TDE: temporary addition (mail was parameter) due to semi-new-API self.ensure_one() body = super(MailMail, self)._send_prepare_body() if self.mailing_id and body and self.mailing_trace_ids: for match in re.findall(tools.URL_REGEX, self.body_html): href = match[0] url = match[1] parsed = werkzeug.urls.url_parse(url, scheme='http') if parsed.scheme.startswith('http') and parsed.path.startswith('/r/'): new_href = href.replace(url, url + '/m/' + str(self.mailing_trace_ids[0].id)) body = body.replace(href, new_href) # generate tracking URL tracking_url = self._get_tracking_url() body = tools.append_content_to_html( body, '<img src="%s"/>' % tracking_url, plaintext=False, ) body = self.env['mail.render.mixin']._replace_local_links(body) return body
def _do_notify_email(self, cr, uid, email_pids, message, force_send=False, user_signature=True, context=None): # compute email body (signature, company data) body_html = message.body # add user signature except for mail groups, where users are usually adding their own signatures already user_id = message.author_id and message.author_id.user_ids and message.author_id.user_ids[0] and message.author_id.user_ids[0].id or None signature_company = self.get_signature_footer(cr, uid, user_id, res_model=message.model, res_id=message.res_id, context=context, user_signature=(user_signature and message.model != 'mail.group')) if signature_company: body_html = tools.append_content_to_html(body_html, signature_company, plaintext=False, container_tag='div') # compute email references references = message.parent_id.message_id if message.parent_id else False # custom values custom_values = dict() if message.model and message.res_id and self.pool.get(message.model) and hasattr(self.pool[message.model], 'message_get_email_values'): custom_values = self.pool[message.model].message_get_email_values(cr, uid, message.res_id, message, context=context) # create email values max_recipients = 50 chunks = [email_pids[x:x + max_recipients] for x in xrange(0, len(email_pids), max_recipients)] email_ids = [] for chunk in chunks: mail_values = { 'mail_message_id': message.id, 'auto_delete': True, 'body_html': body_html, 'recipient_ids': [(4, id) for id in chunk], 'references': references, } mail_values.update(custom_values) email_ids.append(self.pool.get('mail.mail').create(cr, uid, mail_values, context=context)) if force_send and len(chunks) < 2: # for more than 50 followers, use the queue system self.pool.get('mail.mail').send(cr, uid, email_ids, context=context) return True
def test_append_to_html(self): test_samples = [ ('<!DOCTYPE...><HTML encoding="blah">some <b>content</b></HtMl>', '--\nYours truly', True, True, False, '<!DOCTYPE...><html encoding="blah">some <b>content</b>\n<pre>--\nYours truly</pre>\n</html>' ), ('<!DOCTYPE...><HTML encoding="blah">some <b>content</b></HtMl>', '--\nYours truly', True, False, False, '<!DOCTYPE...><html encoding="blah">some <b>content</b>\n<p>--<br/>Yours truly</p>\n</html>' ), ('<html><body>some <b>content</b></body></html>', '--\nYours & <truly>', True, True, False, '<html><body>some <b>content</b>\n<pre>--\nYours & <truly></pre>\n</body></html>' ), ('<html><body>some <b>content</b></body></html>', '<!DOCTYPE...>\n<html><body>\n<p>--</p>\n<p>Yours truly</p>\n</body>\n</html>', False, False, False, '<html><body>some <b>content</b>\n\n\n<p>--</p>\n<p>Yours truly</p>\n\n\n</body></html>' ), ] for html, content, plaintext_flag, preserve_flag, container_tag, expected in test_samples: self.assertEqual( append_content_to_html(html, content, plaintext_flag, preserve_flag, container_tag), expected, 'append_content_to_html is broken')
def send_email(self, options): """ Send by mail the followup to the customer """ partner = self.env['res.partner'].browse(options.get('partner_id')) email = self.env['res.partner'].browse(partner.address_get(['invoice'])['invoice']).email options['keep_summary'] = True if email and email.strip(): # When printing we need te replace the \n of the summary by <br /> tags body_html = self.with_context(print_mode=True, mail=True, lang=partner.lang or self.env.user.lang).get_html(options) start_index = body_html.find(b'<span>', body_html.find(b'<div class="o_account_reports_summary">')) end_index = start_index > -1 and body_html.find(b'</span>', start_index) or -1 if end_index > -1: replaced_msg = body_html[start_index:end_index].replace(b'\n', b'<br />') body_html = body_html[:start_index] + replaced_msg + body_html[end_index:] msg = _('Follow-up email sent to %s') % email # Remove some classes to prevent interactions with messages msg += '<br>' + body_html.decode('utf-8')\ .replace('o_account_reports_summary', '')\ .replace('o_account_reports_edit_summary_pencil', '')\ .replace('fa-pencil', '') msg_id = partner.message_post(body=msg) email = self.env['mail.mail'].create({ 'mail_message_id': msg_id.id, 'subject': _('%s Payment Reminder') % (self.env.user.company_id.name) + ' - ' + partner.name, 'body_html': append_content_to_html(body_html, self.env.user.signature or '', plaintext=False), 'email_from': self.env.user.email or '', 'email_to': email, 'body': msg, }) partner.message_subscribe([partner.id]) return True raise UserError(_('Could not send mail to partner because it does not have any email address defined'))
def send_mail_test(self): self.ensure_one() mails = self.env['mail.mail'] mailing = self.mass_mailing_id test_emails = tools.email_split(self.email_to) for test_mail in test_emails: # Convert links in absolute URLs before the application of the shortener mailing.write({'body_html': self.env['mail.template']._replace_local_links(mailing.body_html)}) mail_values = { 'email_from': mailing.email_from, 'reply_to': mailing.reply_to, 'email_to': test_mail, 'subject': mailing.name, 'body_html': '', 'notification': True, 'mailing_id': mailing.id, 'attachment_ids': [(4, attachment.id) for attachment in mailing.attachment_ids], } mail = self.env['mail.mail'].create(mail_values) unsubscribe_url = mail._get_unsubscribe_url(test_mail) body = tools.append_content_to_html(mailing.body_html, unsubscribe_url, plaintext=False, container_tag='p') mail.write({'body_html': body}) mails |= mail mails.send() return True
def _send_prepare_body(self): """ Override to add the tracking URL to the body and to add Statistic_id in shorted urls """ # TDE: temporary addition (mail was parameter) due to semi-new-API self.ensure_one() body = super(MailMail, self)._send_prepare_body() if self.mailing_id and body and self.statistics_ids: for match in re.findall(URL_REGEX, self.body_html): href = match[0] url = match[1] parsed = werkzeug.urls.url_parse(url, scheme='http') if parsed.scheme.startswith('http') and parsed.path.startswith('/r/'): new_href = href.replace(url, url + '/m/' + str(self.statistics_ids[0].id)) body = body.replace(href, new_href) # generate tracking URL tracking_url = self._get_tracking_url() if tracking_url: body = tools.append_content_to_html(body, tracking_url, plaintext=False, container_tag='div') body = self.env['mail.thread']._replace_local_links(body) return body
def send_email(self): partner = self.env['res.partner'].browse( self.partner_id.address_get(['invoice'])['invoice']) email = partner.email_collections and partner.email_collections or partner.email if email and email.strip(): email = self.env['mail.mail'].create({ 'subject': _('%s Payment Reminder') % (self.env.user.company_id.name) + ' - ' + self.partner_id.name, 'body_html': append_content_to_html(self.with_context( public=True, mode='print').get_html(), self.env.user.signature, plaintext=False), 'email_from': self.env.user.email or '', 'email_to': email, }) msg = self._get_email_sent_log() msg += '<br>' + ustr( self.with_context(public=True, mode='print').get_html()) self.partner_id.message_post( body=msg, subtype='account_reports.followup_logged_action') return True return False
def _moderate_send_reject_email(self, subject, comment): for message in self: if not message.email_from: continue body_html = append_content_to_html('<div>%s</div>' % ustr(comment), message.body, plaintext=False) body_html = self.env['mail.render.mixin']._replace_local_links( body_html) self.env['mail.mail'].sudo().create({ 'author_id': self.env.user.partner_id.id, 'auto_delete': True, 'body_html': body_html, 'email_from': self.env.user.email_formatted or self.env.company.catchall_formatted, 'email_to': message.email_from, 'references': message.mail_message_id.message_id, 'subject': subject, 'state': 'outgoing', })
def send_get_mail_body(self, partner=None): """ Override to add the tracking URL to the body and to add Statistic_id in shorted urls """ # TDE: temporary addition (mail was parameter) due to semi-new-API self.ensure_one() body = super(MailMail, self).send_get_mail_body(partner=partner) if self.mailing_id and body and self.statistics_ids: for match in re.findall(URL_REGEX, self.body_html): href = match[0] url = match[1] parsed = werkzeug.urls.url_parse(url, scheme='http') if parsed.scheme.startswith('http') and parsed.path.startswith('/r/'): new_href = href.replace(url, url + '/m/' + str(self.statistics_ids[0].id)) body = body.replace(href, new_href) body = self.env['mail.thread']._replace_local_links(body) # generate tracking URL if self.statistics_ids: tracking_url = self._get_tracking_url(partner) if tracking_url: body = tools.append_content_to_html(body, tracking_url, plaintext=False, container_tag='div') return body
def send_email(self, options): partner = self.env['res.partner'].browse(options.get('partner_id')) # José Candelas # original = email = self.env['res.partner'].browse(partner.address_get(['invoice'])['invoice']).email email = partner.email if email and email.strip(): body_html = self.with_context(print_mode=True, mail=True, keep_summary=True).get_html(options) msg = self.get_post_message(options) msg += '<br>' + body_html.decode('utf-8') msg_id = partner.message_post( body=msg, subtype='account_reports.followup_logged_action') email = self.env['mail.mail'].create({ 'mail_message_id': msg_id.id, 'subject': _('%s Payment Reminder') % (self.env.user.company_id.name) + ' - ' + partner.name, 'body_html': append_content_to_html(body_html, self.env.user.signature or '', plaintext=False), 'email_from': self.env.user.email or '', 'email_to': email, 'body': msg, }) return True raise UserError( _('Could not send mail to partner because it does not have any email address defined' ))
def _send_prepare_body(self): """ Short-circuit parent method for mail groups, replace the default footer with one appropriate for mailing-lists.""" if self.model == 'mail.channel' and self.res_id: # no super() call on purpose, no private links that could be quoted! channel = self.env['mail.channel'].browse(self.res_id) base_url = self.env['ir.config_parameter'].sudo().get_param( 'web.base.url') vals = { 'maillist': _('Mailing-List'), 'post_to': _('Post to'), 'unsub': _('Unsubscribe'), 'mailto': 'mailto:%s@%s' % (channel.alias_name, channel.alias_domain), 'group_url': '%s/groups/%s' % (base_url, slug(channel)), 'unsub_url': '%s/groups?unsubscribe' % (base_url, ), } footer = """_______________________________________________ %(maillist)s: %(group_url)s %(post_to)s: %(mailto)s %(unsub)s: %(unsub_url)s """ % vals body = tools.append_content_to_html(self.body, footer, container_tag='div') return body else: return super(MailMail, self)._send_prepare_body()
def onchange_template_id(self, template_id, composition_mode, model, res_id): """ - mass_mailing: we cannot render, so return the template values - normal mode: return rendered values /!\ for x2many field, this onchange return command instead of ids """ if template_id and composition_mode == 'mass_mail': template = self.env['mail.template'].browse(template_id) fields = ['subject', 'body_html', 'email_from', 'reply_to', 'mail_server_id'] values = dict((field, getattr(template, field)) for field in fields if getattr(template, field)) if template.attachment_ids: values['attachment_ids'] = [att.id for att in template.attachment_ids] if template.mail_server_id: values['mail_server_id'] = template.mail_server_id.id if template.user_signature and 'body_html' in values: signature = self.env.user.signature values['body_html'] = tools.append_content_to_html(values['body_html'], signature, plaintext=False) if template.report_template: attachment = self.env['ir.attachment'] attach = self.generate_attachment_from_report(template_id, res_id) for attach_fname, attach_datas in attach[res_id].pop('attachments', []): data_attach = { 'name': attach_fname, 'datas': attach_datas, 'datas_fname': attach_fname, 'res_model': 'mail.compose.message', 'res_id': 0, 'type': 'binary', } values.setdefault('attachment_ids', list()).append(attachment.create(data_attach).id) elif template_id: values = self.generate_email_for_composer(template_id, [res_id])[res_id] # 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', '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.with_context(default_composition_mode=composition_mode, default_model=model, default_res_id=res_id).default_get(['composition_mode', 'model', 'res_id', 'parent_id', 'partner_ids', 'subject', 'body', 'email_from', 'reply_to', 'attachment_ids', 'mail_server_id']) values = dict((key, default_values[key]) for key in ['subject', 'body', 'partner_ids', 'email_from', 'reply_to', 'attachment_ids', 'mail_server_id'] if key in default_values) if values.get('body_html'): values['body'] = values.pop('body_html') # 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) return {'value': values}
def tracking_img_add(self, email): self.ensure_one() tracking_url = self._get_mail_tracking_img() if tracking_url: body = tools.append_content_to_html( email.get('body', ''), tracking_url, plaintext=False, container_tag='div') email['body'] = body return email
def onchange_template_id(self, template_id, composition_mode, model, res_id): """ - mass_mailing: we cannot render, so return the template values - normal mode: return rendered values /!\ for x2many field, this onchange return command instead of ids """ if template_id and composition_mode == 'mass_mail': template = self.env['mail.template'].browse(template_id) print('-------------', template) fields = [ 'subject', 'body_html', 'email_from', 'reply_to', 'mail_server_id' ] values = dict((field, getattr(template, field)) for field in fields if getattr(template, field)) if template.attachment_ids: values['attachment_ids'] = [ att.id for att in template.attachment_ids ] if template.mail_server_id: values['mail_server_id'] = template.mail_server_id.id if template.user_signature and 'body_html' in values: signature = self.env.user.signature values['body_html'] = tools.append_content_to_html( values['body_html'], signature, plaintext=False) elif template_id: values = self.generate_email_for_composer(template_id, [res_id])[res_id] print('-----------onchange_template_id in else condition') else: default_values = self.with_context( default_composition_mode=composition_mode, default_model=model, default_res_id=res_id).default_get([ 'composition_mode', 'model', 'res_id', 'parent_id', 'partner_ids', 'subject', 'body', 'email_from', 'reply_to', 'attachment_ids', 'mail_server_id' ]) values = dict((key, default_values[key]) for key in [ 'subject', 'body', 'partner_ids', 'email_from', 'reply_to', 'attachment_ids', 'mail_server_id' ] if key in default_values) if values.get('body_html'): values['body'] = values.pop('body_html') # 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) return {'value': values}
def _notify_members(self, message): """Send the given message to all members of the mail group (except the author).""" self.ensure_one() if message.mail_group_id != self: raise UserError(_('The group of the message do not match.')) if not message.mail_message_id.reply_to: _logger.error('The alias or the catchall domain is missing, group might not work properly.') base_url = self.get_base_url() body = self.env['mail.render.mixin']._replace_local_links(message.body) access_token = self._generate_group_access_token() mail_values = [] for batch_members in tools.split_every(GROUP_SEND_BATCH_SIZE, self.member_ids): for member in batch_members: if member.email_normalized == message.email_from_normalized: # Do not send the email to his author continue # SMTP headers related to the subscription email_url_encoded = urls.url_quote(member.email_normalized) headers = { 'List-Archive': f'<{base_url}/groups/{slug(self)}>', 'List-Subscribe': f'<{base_url}/groups?email={email_url_encoded}>', 'List-Unsubscribe': f'<{base_url}/groups?unsubscribe&email={email_url_encoded}>', } # Add the footer (member specific) in the body template_values = { 'mailto': f'{self.alias_name}@{self.alias_domain}', 'group_url': f'{base_url}/groups/{slug(self)}', 'unsub_url': f'{base_url}/groups?unsubscribe&group_id={self.id}&token={access_token}' } template = self.env.ref('mail_group.mail_group_footer') footer = template._render(template_values, engine='ir.qweb', minimal_qcontext=True) member_body = tools.append_content_to_html(body, footer) mail_values.append({ 'auto_delete': True, 'attachment_ids': message.attachment_ids.ids, 'body_html': member_body, 'email_from': message.email_from, 'email_to': member.email, 'headers': json.dumps(headers), 'mail_message_id': message.mail_message_id.id, 'message_id': message.mail_message_id.message_id, 'model': 'mail.group', 'reply_to': message.mail_message_id.reply_to, 'res_id': self.id, 'subject': message.subject, }) if mail_values: self.env['mail.mail'].sudo().create(mail_values)
def test_append_to_html(self): test_samples = [ ('<!DOCTYPE...><HTML encoding="blah">some <b>content</b></HtMl>', '--\nYours truly', True, True, False, '<!DOCTYPE...><html encoding="blah">some <b>content</b>\n<pre>--\nYours truly</pre>\n</html>'), ('<!DOCTYPE...><HTML encoding="blah">some <b>content</b></HtMl>', '--\nYours truly', True, False, False, '<!DOCTYPE...><html encoding="blah">some <b>content</b>\n<p>--<br/>Yours truly</p>\n</html>'), ('<html><body>some <b>content</b></body></html>', '<!DOCTYPE...>\n<html><body>\n<p>--</p>\n<p>Yours truly</p>\n</body>\n</html>', False, False, False, '<html><body>some <b>content</b>\n\n\n<p>--</p>\n<p>Yours truly</p>\n\n\n</body></html>'), ] for html, content, plaintext_flag, preserve_flag, container_tag, expected in test_samples: self.assertEqual(append_content_to_html(html, content, plaintext_flag, preserve_flag, container_tag), expected, 'append_content_to_html is broken')
def generate_sms(self, res_ids, fields=None): 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 = ['body_html'] 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['sms.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 # 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['message'] = tools.html_sanitize( values['body_html'] ) # technical settings values.update( model=template.model, res_id=res_id or False, ) return multi_mode and results or results[res_ids[0]]
def send_message_on_whatsapp(self): Param = self.env['res.config.settings'].sudo().get_values() res_partner_id = self.env['res.partner'].search([('id', '=', self.user_id.partner_id.id)]) res_user_id = self.env['res.users'].search([('id', '=', self.env.user.id)]) if res_partner_id.country_id.phone_code and res_partner_id.mobile: msg = '' if self.project_id.name: msg += "*Project:* "+self.project_id.name if self.name: msg += "\n*Task name:* "+self.name if self.date_deadline: msg+= "\n*Deadline:* "+str(self.date_deadline) if len(self.description) > 11: msg += "\n*Description:* "+self.cleanhtml(self.description) msg = "Hello " + res_partner_id.name + "," + "\nNew task assigned to you" + "\n" + msg # msg = "Hello " + res_partner_id.name+","+ "\nNew task assigned to you"+"\n"+"*Project:* "+self.project_id.name+"\n*Task name:* "+self.name+"\n*Deadline:* "+str( # self.date_deadline)+"\n*Description:* "+self.cleanhtml(self.description) if res_user_id.has_group('pragmatic_odoo_whatsapp_integration.group_project_enable_signature'): user_signature = self.cleanhtml(res_user_id.signature) msg += "\n\n" + user_signature url = 'https://api.chat-api.com/instance' + Param.get('whatsapp_instance_id') + '/sendMessage?token=' + Param.get('whatsapp_token') headers = { "Content-Type": "application/json", } whatsapp_msg_number = res_partner_id.mobile whatsapp_msg_number_without_space = whatsapp_msg_number.replace(" ", ""); whatsapp_msg_number_without_code = whatsapp_msg_number_without_space.replace('+' + str(res_partner_id.country_id.phone_code), "") tmp_dict = { # "phone": "+" + str(res_partner_id.country_id.phone_code) + "" + res_partner_id.mobile, "phone": "+" + str(res_partner_id.country_id.phone_code) + "" + whatsapp_msg_number_without_code, # "body": "Hello "+res_partner_id.name+","+ "\nNew task assigned to you"+"\n"+"*"+"Project:"+"*"+self.project_id.name "body": msg } response = requests.post(url, json.dumps(tmp_dict), headers=headers) if response.status_code == 201 or response.status_code == 200: _logger.info("\nSend Message successfully") response_dict = response.json() self.whatsapp_msg_id = response_dict.get('id') mail_message_obj = self.env['mail.message'] comment = "fa fa-whatsapp" body_html = tools.append_content_to_html('<div class = "%s"></div>' % tools.ustr(comment), msg) body_msg = self.convert_to_html(body_html) if self.env['ir.config_parameter'].sudo().get_param('pragmatic_odoo_whatsapp_integration.group_project_display_chatter_message'): mail_message_id = mail_message_obj.sudo().create({ 'res_id': self.id, 'model': 'project.task', 'body': body_msg, })
def onchange_template_id(self, template_id, composition_mode, model, res_id): """ Append the quote of previous e-mail to the body of the message. """ result = super().onchange_template_id( template_id, composition_mode, model, res_id ) reply_quote = self.env.context.get("reply_quote") if reply_quote: result["value"]["body"] = append_content_to_html( result["value"]["body"], "<br/><br/>" + reply_quote, plaintext=False ) return result
def tracking_img_add(self, email): self.ensure_one() tracking_url = self._get_mail_tracking_img() if tracking_url: content = email.get('body', '') content = re.sub( r'<img[^>]*data-odoo-tracking-email=["\'][0-9]*["\'][^>]*>', '', content) body = tools.append_content_to_html( content, tracking_url, plaintext=False, container_tag='div') email['body'] = body return email
def onchange_template_id(self, template_id, composition_mode, model, res_id): """ Append the quote of previous e-mail to the body of the message. """ result = super(MailComposer, self).onchange_template_id( template_id, composition_mode, model, res_id ) reply_quote = self.env.context.get('reply_quote') if reply_quote: result['value']['body'] = append_content_to_html( result['value']['body'], '<br/><br/>' + reply_quote, plaintext=False) return result
def send_email(self, options): if options and "partner_id" in options: partner_id = self.env['res.partner'].browse( options.get('partner_id')) email = self.env['res.partner'].browse( partner_id.address_get(['invoice'])['invoice']).email if email and email.strip(): # Get report lines, containing invoice number lines = self.env['account.followup.report'].with_context( lang=partner_id.lang, public=True).get_lines(options) ids = [] for line in lines: if line['name'] == '': continue if line['action'][1]: ids.append(line['action'][1]) #Get all invoices related to numbers then browse it. invoices = self.env['account.invoice'].search([('id', 'in', ids)]) for invoice in invoices: # Create ir.attachment and PDF for invoice when it doesn't exists pdf = self.env.ref( 'account.account_invoices').sudo().render_qweb_pdf( [invoice.id])[0] attachments = self.env['ir.attachment'].search([ ('res_id', 'in', invoices.mapped('id')), ('res_model', '=', "account.invoice") ]).mapped('id') # Attach to all related PDF to email email = self.env['mail.mail'].create({ 'subject': _('%s Payment Reminder') % self.env.user.company_id.name, 'body_html': append_content_to_html(self.with_context( public=True, mode='print').get_html(options), self.env.user.signature, plaintext=False), 'email_from': self.env.user.email or '', 'email_to': email, 'attachment_ids': [(6, 0, attachments)] }) msg = _(': Sent a followup email') partner_id.message_post( body=msg, subtype='account_reports.followup_logged_action') return True return False
def onchange_template_id(self, template_id, composition_mode, model, res_id): """ - mass_mailing: we cannot render, so return the template values - normal mode: return rendered values /!\ for x2many field, this onchange return command instead of ids """ if template_id and composition_mode == 'mass_mail': template = self.env['mail.template'].browse(template_id) fields = ['subject', 'body_html', 'email_from', 'reply_to', 'mail_server_id'] values = dict((field, getattr(template, field)) for field in fields if getattr(template, field)) if template.attachment_ids: values['attachment_ids'] = [att.id for att in template.attachment_ids] if template.mail_server_id: values['mail_server_id'] = template.mail_server_id.id if template.user_signature and 'body_html' in values: signature = self.env.user.signature values['body_html'] = tools.append_content_to_html(values['body_html'], signature, plaintext=False) elif template_id: values = self.generate_email_for_composer(template_id, [res_id])[res_id] # 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_ids = [] 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', 'res_id': 0, 'type': 'binary', # override default_type from context, possibly meant for another model! } attachment_ids.append(Attachment.create(data_attach).id) if values.get('attachment_ids', []) or attachment_ids: values['attachment_ids'] = [(5,)] + values.get('attachment_ids', []) + attachment_ids else: default_values = self.with_context(default_composition_mode=composition_mode, default_model=model, default_res_id=res_id).default_get(['composition_mode', 'model', 'res_id', 'parent_id', 'partner_ids', 'subject', 'body', 'email_from', 'reply_to', 'attachment_ids', 'mail_server_id']) values = dict((key, default_values[key]) for key in ['subject', 'body', 'partner_ids', 'email_from', 'reply_to', 'attachment_ids', 'mail_server_id'] if key in default_values) if values.get('body_html'): values['body'] = values.pop('body_html') # 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) return {'value': values}
def onchange_template_id(self): template = self.env['mail.template'].browse(self.template_id.id) if template: attributes = ['subject', 'body_html', 'email_from'] values = dict((attribute, getattr(template, attribute)) for attribute in attributes if getattr(template, attribute)) if template.user_signature and 'body_html' in values: signature = self.env.user.signature values['body_html'] = tools.append_content_to_html( values['body_html'], signature, plaintext=False) return values
def test_clean_email_body(self): template = self.env.ref('mail_group.mail_group_footer') footer = template._render({'group_url': 'Test remove footer'}, engine='ir.qweb', minimal_qcontext=True) body = append_content_to_html("<div>Test email body</div>", footer, plaintext=False) result = self.env['mail.group']._clean_email_body(body) self.assertIn('Test email body', result, 'Should have kept the original email body') self.assertNotIn('Test remove footer', result, 'Should have removed the mailing list footer') self.assertNotIn('o_mg_message_footer', result, 'Should have removed the entire HTML element')
def check_template_change(self): """ - mass_mailing: we cannot render, so return the template values - normal mode: return rendered values """ if self.template_id and self.template_id.id: self.subject = self.template_id.subject self.body_html = self.template_id.body_html self.reply_to = self.template_id.reply_to self.mail_server_id = self.template_id.mail_server_id if self.template_id.attachment_ids: self.attachment_ids = [att.id for att in template.attachment_ids] if self.template_id.mail_server_id: self.mail_server_id = self.template_id.mail_server_id.id if self.template_id.user_signature and self.body_html: signature = self.env['res.users'].browse(self._uid).signature self.body = tools.append_content_to_html(self.body, signature, plaintext=False) else: if not self.body_html: signature = self.env['res.users'].browse(self._uid).signature self.body_html = signature
def get_body_html(self, options): partner = self.env['res.partner'].browse(options.get('partner_id')) options['keep_summary'] = True body_html = self.with_context(print_mode=True, mail=True, lang=partner.lang or self.env.user.lang).get_html(options) body = append_content_to_html(body_html, self.env.user.signature or '', plaintext=False) body = body.replace("<thead>", "<tbody>") body = body.replace("</thead>", "</tbody>") body = body.replace("<th>", "<td>") body = body.replace("</th>", "</td>") body = body.replace("<thead", "<tbody") body = body.replace("<th", "<td") template = self.env.ref('fal_customer_statement.email_subject_fal_customer_statement') template.sudo().write({'body_html': body}) res = { 'default_partner_ids': [partner.id], 'default_template_id': template.id, 'default_model' : 'account.followup.report', } return res
def send_get_mail_body(self, partner=None): """ add a signin link inside the body of a mail.mail :param mail: mail.mail browse_record :param partner: browse_record of the specific recipient partner :return: the resulting body_html """ partner_obj = self.env['res.partner'] body = self.body_html if partner: self = self.with_context(signup_valid=True) partner = partner_obj.sudo().browse(partner.id) text = _( """<p>Access your messages and personal documents through <a href="%s">our Customer Portal</a></p>""" ) % partner.signup_url # partner is an user: add a link to the document if read access if partner.user_ids and self.model and self.res_id \ and self.check_access_rights('read', raise_exception=False): related_user = partner.user_ids[0] try: self.env[self.model].check_access_rule('read') if 'Your timesheet is pending' in body: url = partner.with_context( signup_valid=True )._get_signup_url_for_action( action= 'bista_iugroup.action_event_user_form_timesheet_language', res_id=self.res_id, view_type='form', model=self.model)[partner.id] else: url = partner.with_context( signup_valid=True)._get_signup_url_for_action( action='', res_id=self.res_id, view_type='form', model=self.model)[partner.id] text = _( """<p>Access this document <a href="%s">directly in IUX</a></p>""" ) % url except Exception, e: pass body = tools.append_content_to_html( body, ("<div><p>%s</p></div>" % text), plaintext=False)
def create(self, vals): action = super().create(vals) commercial_partner = self.env['res.partner'].browse( vals['commercial_partner_id']) xmlid = 'account_invoice_overdue_reminder.'\ 'overdue_invoice_reminder_mail_template' mail_tpl = self.env.ref(xmlid) mail_tpl_lang = mail_tpl.with_context(lang=commercial_partner.lang or 'en_US') mail_subject = mail_tpl_lang._render_template( mail_tpl_lang.subject, self._name, action.id) mail_body = mail_tpl_lang._render_template( mail_tpl_lang.body_html, self._name, action.id) if mail_tpl.user_signature: signature = self.env.user.signature if signature: mail_body = tools.append_content_to_html( mail_body, signature, plaintext=False) mail_body = tools.html_sanitize(mail_body) action.write({ 'mail_subject': mail_subject, 'mail_body': mail_body, }) return action
def send_email(self, options): partner = self.env['res.partner'].browse(options.get('partner_id')) email = self.env['res.partner'].browse(partner.address_get(['invoice'])['invoice']).email template = self.env.ref('customer_statement_email.email_sustomer_statements') template_obj = self.env['mail.template'] mail_mail_obj = self.env['mail.mail'] attachment_obj = self.env['ir.attachment'] if email and email.strip(): values = template.generate_email(partner.id) atta_id = '' for attachment in values.get('attachments', []): attachment_data = { 'name': partner.name + ' Customer Statement', 'datas_fname': partner.name + " Customer Statement.pdf", 'datas': attachment[1], 'res_model': 'res.partner', 'res_id': partner.id } atta_id = (attachment_obj.create(attachment_data).id) body_html = self.with_context(print_mode=True, mail=True, keep_summary=True).get_html(options) html_body = b'<style>table {display:none}</style>' body_html = html_body + body_html msg = _('Follow-up email sent to %s') % email msg += '<br>' + body_html.decode('utf-8') msg_id = partner.message_post(body=msg, subtype='account_reports.followup_logged_action') msg_id.write({'attachment_ids': [(6, 0, [atta_id])]}) email = self.env['mail.mail'].with_context(default_mail_message_id=msg_id).create({ 'subject': _('%s Customer Statement') % (self.env.user.company_id.name) + ' - ' + partner.name, 'body_html': append_content_to_html(body_html, self.env.user.signature or '', plaintext=False), 'email_from': self.env.user.email or '', 'email_to': email, 'body': msg, }) return True raise UserError(_('Could not send mail to partner because it does not have any email address defined'))
def send_get_mail_body(self, partner=None): """ Short-circuit parent method for mail groups, replace the default footer with one appropriate for mailing-lists.""" if self.model == 'mail.channel' and self.res_id: # no super() call on purpose, no private links that could be quoted! channel = self.env['mail.channel'].browse(self.res_id) base_url = self.env['ir.config_parameter'].get_param('web.base.url') vals = { 'maillist': _('Mailing-List'), 'post_to': _('Post to'), 'unsub': _('Unsubscribe'), 'mailto': 'mailto:%s@%s' % (channel.alias_name, channel.alias_domain), 'group_url': '%s/groups/%s' % (base_url, slug(channel)), 'unsub_url': '%s/groups?unsubscribe' % (base_url,), } footer = """_______________________________________________ %(maillist)s: %(group_url)s %(post_to)s: %(mailto)s %(unsub)s: %(unsub_url)s """ % vals body = tools.append_content_to_html(self.body, footer, container_tag='div') return body else: return super(MailMail, self).send_get_mail_body(partner=partner)
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, (int, long)): 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", ] 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.iteritems(): templates_to_res_ids.setdefault(template, []).append(res_id) results = dict() for template, template_res_ids in templates_to_res_ids.iteritems(): 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.iteritems(): results.setdefault(res_id, dict())[field] = field_value # compute recipients if any(field in fields for field in ["email_to", "partner_to", "email_cc"]): 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 and not "report_template_in_attachment" in self.env.context: 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 in ["qweb-html", "qweb-pdf"]: result, format = Template.env["report"].get_pdf([res_id], report_service), "pdf" else: result, format = odoo_report.render_report( self._cr, self._uid, [res_id], report_service, {"model": template.model}, Template._context ) # TODO in trunk, change return format to binary to match message_post expected format 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]]
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' ] 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']): 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]) # TODO in trunk, change return format to binary to match message_post expected format 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]]
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 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'] 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']): 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]) # TODO in trunk, change return format to binary to match message_post expected format 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]]
def fetch_mail(self): for server in self: count, failed = 0, 0 pop_server = None if server.type == 'pop': _logger.info('Server tpye is POP') try: while True: pop_server = server.connect() (num_messages, total_size) = pop_server.stat() pop_server.list() _logger.info('Server tpye is POP inside while') _logger.info('total_size = %d', total_size) _logger.info('num_messages = %d', num_messages) for num in range( 1, min(MAX_POP_MESSAGES, num_messages) + 1): _logger.info( 'Server tpye is POP inside while INSIDE FOR') (header, messages, octets) = pop_server.retr(num) message = (b'\n').join(messages) res_id = None response = { 'errorCode': 100, 'message': 'File Uploaded Successfully' } try: if isinstance(message, xmlrpclib.Binary): message = bytes(message.data) if isinstance(message, pycompat.text_type): message = message.encode('utf-8') extract = getattr(email, 'message_from_bytes', email.message_from_string) message = extract(message) if not isinstance(message, Message): message = pycompat.to_native(message) message = email.message_from_string( message) email_to = tools.decode_message_header( message, 'To') match = re.search(r'[\w\.-]+@[\w\.-]+', email_to) email_to = str(match.group(0)) _logger.info('Email to %r', email_to) # if email_to == INCOMING_EMAIL_ID: _Attachment = namedtuple( 'Attachment', ('fname', 'content', 'info')) attachments = [] body = u'' email_from = tools.decode_message_header( message, 'From') _logger.info('Email from %r', email_from) match = re.search(r'[\w\.-]+@[\w\.-]+', email_from) email_from = str(match.group(0)) subject = tools.decode_message_header( message, 'Subject') tmpl_type = None if 'Inventory' in subject: tmpl_type = "Inventory" elif 'Requirement' in subject: tmpl_type = "Requirement" if message.get_content_maintype() != 'text': alternative = False for part in message.walk(): if part.get_content_type( ) == 'multipart/alternative': alternative = True if part.get_content_maintype( ) == 'multipart': continue # skip container filename = part.get_param( 'filename', None, 'content-disposition') if not filename: filename = part.get_param( 'name', None) if filename: if isinstance(filename, tuple): filename = email.utils.collapse_rfc2231_value( filename).strip() else: filename = tools.decode_smtp_header( filename) encoding = part.get_content_charset() if filename and part.get('content-id'): inner_cid = part.get( 'content-id').strip('><') attachments.append( _Attachment( filename, part.get_payload( decode=True), {'cid': inner_cid})) continue if filename or part.get( 'content-disposition', '' ).strip().startswith('attachment'): attachments.append( _Attachment( filename or 'attachment', part.get_payload( decode=True), {})) continue if part.get_content_type( ) == 'text/plain' and (not alternative or not body): body = tools.append_content_to_html( body, tools.ustr(part.get_payload( decode=True), encoding, errors='replace'), preserve=True) elif part.get_content_type( ) == 'text/html': body = tools.ustr( part.get_payload(decode=True), encoding, errors='replace') else: attachments.append( _Attachment( filename or 'attachment', part.get_payload( decode=True), {})) if len(attachments) > 0: encoding = message.get_content_charset( ) plain_text = html2text.HTML2Text() message_payload = plain_text.handle( tools.ustr(body, encoding, errors='replace')) if '- Forwarded message -' in message_payload: messages = message_payload.split( '- Forwarded message -') _logger.info( 'Forwarded message payload: %r', messages) total_parts = len(messages) originator_part = messages[ total_parts - 1] _logger.info( 'originator_part: %r', originator_part) match = re.search( r'[\w\.-]+@[\w\.-]+', originator_part) _logger.info('match: %r', match) if match: email_from_domain = re.search( "@[\w.]+", email_from).group(0) _logger.info( 'email_from_domain: %r', email_from_domain) email_to_domain = re.search( "@[\w.]+", email_to).group(0) _logger.info( 'email_to_domain: %r', email_to_domain) if email_to_domain != email_from_domain: email_from = None else: email_from = str( match.group(0)) _logger.info( 'email_to_domain email_from: %r', email_from) #_logger.info('message payload: %r %r', message_payload, email_from) if not email_from is None: users_model = self.env[ 'res.partner'].search([ ("email", "=", email_from) ]) if users_model: if len(users_model) == 1: user_attachment_dir = ATTACHMENT_DIR + str( datetime.now( ).strftime("%d%m%Y") ) + "/" + str( users_model.id) + "/" if not os.path.exists( os.path.dirname( user_attachment_dir )): try: os.makedirs( os.path. dirname( user_attachment_dir )) except OSError as exc: if exc.errno != errno.EEXIST: raise for attachment in attachments: filename = getattr( attachment, 'fname') if not filename is None: try: file_contents_bytes = getattr( attachment, 'content') file_path = user_attachment_dir + str( filename) file_ref = open( str(file_path ), "wb+") file_ref.write( file_contents_bytes ) file_ref.close( ) response = self.env[ 'sps.document.process'].process_document( users_model, file_path, tmpl_type, filename, 'Email' ) except Exception as e: _logger.info( str(e)) else: _logger.error( 'Presents Same Email Id for multiple users %r', email_from) response = dict( errorCode=101, message= 'Presents Same Email Id for multiple users : ' + str(email_from)) else: _logger.info( 'user not found for %r', email_from) response = dict( errorCode=102, message= 'User not found for : ' + str(email_from)) else: _logger.info( 'domain not matched for forwarded email' ) response = dict( errorCode=103, message= 'Domain not matched for forwarded email : ' + str(email_from)) else: _logger.info("No attachements found") response = dict( errorCode=104, message='No attachements found : ' + str(email_from)) else: _logger.info('Not a Multipart email') response = dict( errorCode=105, message='Not a Multipart email' + str(email_from)) pop_server.dele(num) if "errorCode" in response: self.send_mail( "Sending Email Response as " + str(response['message']) + " for user " + str(email_from)) except Exception: _logger.info( 'Failed to process mail from %s server %s.', server.type, server.name, exc_info=True) failed += 1 if res_id and server.action_id: server.action_id.with_context({ 'active_id': res_id, 'active_ids': [res_id], 'active_model': self.env.context.get( "thread_model", server.object_id.model) }).run() self.env.cr.commit() _logger.info('num_messages = %d', num_messages) if num_messages < MAX_POP_MESSAGES: break pop_server.quit() _logger.info( "Fetched %d email(s) on %s server %s; %d succeeded, %d failed.", num_messages, server.type, server.name, (num_messages - failed), failed) except Exception: _logger.info( "General failure when trying to fetch mail from %s server %s.", server.type, server.name, exc_info=True) finally: _logger.info('Server tpye is POP inside finally') if pop_server: pop_server.quit() server.write({'date': fields.Datetime.now()}) return super(IncomingMailCronModel, self).fetch_mail()