From ad1c04850cdf1aac8c8ab2e809b8a8298725b577 Mon Sep 17 00:00:00 2001 From: Makarand Bauskar Date: Wed, 27 Sep 2017 12:41:35 +0530 Subject: [PATCH] [hotfix] send email from sender's email account if From field is selected on communication view (#4181) * [hotfix] send email from sender's email account if From field is selected on communication view * [fixes] codecy fixes --- frappe/core/doctype/communication/email.py | 6 ++++++ frappe/email/email_body.py | 8 ++++---- frappe/email/queue.py | 4 ++-- frappe/email/smtp.py | 24 +++++++++++++++------- 4 files changed, 29 insertions(+), 13 deletions(-) diff --git a/frappe/core/doctype/communication/email.py b/frappe/core/doctype/communication/email.py index b8a8b4ec30..04bc906161 100755 --- a/frappe/core/doctype/communication/email.py +++ b/frappe/core/doctype/communication/email.py @@ -287,6 +287,12 @@ def set_incoming_outgoing_accounts(doc): if not doc.outgoing_email_account: doc.outgoing_email_account = frappe.db.get_value("Email Account", {"default_outgoing": 1, "enable_outgoing": 1}, + ["email_id", "always_use_account_email_id_as_sender", "name", "send_unsubscribe_message"],as_dict=True) or frappe._dict() + + if not doc.outgoing_email_account: + # if from address is not the default email account + doc.outgoing_email_account = frappe.db.get_value("Email Account", + {"email_id": doc.sender, "enable_outgoing": 1}, ["email_id", "always_use_account_email_id_as_sender", "name", "send_unsubscribe_message"], as_dict=True) or frappe._dict() if doc.sent_or_received == "Sent": diff --git a/frappe/email/email_body.py b/frappe/email/email_body.py index cf36aac68e..638905c391 100755 --- a/frappe/email/email_body.py +++ b/frappe/email/email_body.py @@ -73,14 +73,14 @@ class EMail: self.cc = cc or [] self.html_set = False - self.email_account = email_account or get_outgoing_email_account() + self.email_account = email_account or get_outgoing_email_account(sender=sender) def set_html(self, message, text_content = None, footer=None, print_html=None, formatted=None, inline_images=None, header=None): """Attach message in the html portion of multipart/alternative""" if not formatted: formatted = get_formatted_html(self.subject, message, footer, print_html, - email_account=self.email_account, header=header) + email_account=self.email_account, header=header, sender=self.sender) # this is the first html part of a multi-part message, # convert to text well @@ -231,9 +231,9 @@ class EMail: return self.msg_root.as_string() def get_formatted_html(subject, message, footer=None, print_html=None, - email_account=None, header=None, unsubscribe_link=None): + email_account=None, header=None, unsubscribe_link=None, sender=None): if not email_account: - email_account = get_outgoing_email_account(False) + email_account = get_outgoing_email_account(False, sender=sender) rendered_email = frappe.get_template("templates/emails/standard.html").render({ "header": get_header(header), diff --git a/frappe/email/queue.py b/frappe/email/queue.py index 0452cba5bc..55713f074f 100755 --- a/frappe/email/queue.py +++ b/frappe/email/queue.py @@ -64,7 +64,7 @@ def send(recipients=None, sender=None, subject=None, message=None, text_content= if isinstance(send_after, int): send_after = add_days(nowdate(), send_after) - email_account = get_outgoing_email_account(True, append_to=reference_doctype) + email_account = get_outgoing_email_account(True, append_to=reference_doctype, sender=sender) if not sender or sender == "Administrator": sender = email_account.default_sender @@ -401,7 +401,7 @@ def send_one(email, smtpserver=None, auto_commit=True, now=False, from_test=Fals try: if not frappe.flags.in_test: if not smtpserver: smtpserver = SMTPServer() - smtpserver.setup_email_account(email.reference_doctype) + smtpserver.setup_email_account(email.reference_doctype, sender=email.sender) for recipient in recipients_list: if recipient.status != "Not Sent": diff --git a/frappe/email/smtp.py b/frappe/email/smtp.py index db82d937ee..1c6b2d89df 100644 --- a/frappe/email/smtp.py +++ b/frappe/email/smtp.py @@ -7,8 +7,8 @@ import frappe import smtplib import email.utils import _socket, sys -from frappe.utils import cint from frappe import _ +from frappe.utils import cint, parse_addr def send(email, append_to=None, retry=1): """Deprecated: Send the message or add it to Outbox Email""" @@ -35,22 +35,32 @@ def send(email, append_to=None, retry=1): _send(retry) -def get_outgoing_email_account(raise_exception_not_set=True, append_to=None): +def get_outgoing_email_account(raise_exception_not_set=True, append_to=None, sender=None): """Returns outgoing email account based on `append_to` or the default outgoing account. If default outgoing account is not found, it will try getting settings from `site_config.json`.""" + sender_email_id = None + if sender: + sender_email_id = parse_addr(sender)[1] + if not getattr(frappe.local, "outgoing_email_account", None): frappe.local.outgoing_email_account = {} - if not frappe.local.outgoing_email_account.get(append_to or "default"): + if not frappe.local.outgoing_email_account.get(append_to or sender_email_id or "default"): email_account = None if append_to: # append_to is only valid when enable_incoming is checked email_account = _get_email_account({"enable_outgoing": 1, "enable_incoming": 1, "append_to": append_to}) + if not email_account and sender_email_id: + # check if the sender has email account with enable_outgoing + email_account = _get_email_account({"enable_outgoing": 1, "email_id": sender_email_id}) + if not email_account: + # sender don't have the outging email account + sender_email_id = None email_account = get_default_outgoing_email_account(raise_exception_not_set=raise_exception_not_set) if not email_account and raise_exception_not_set and cint(frappe.db.get_single_value('System Settings', 'setup_complete')): @@ -65,9 +75,9 @@ def get_outgoing_email_account(raise_exception_not_set=True, append_to=None): email_account.password = email_account.get_password(raise_exception=raise_exception) email_account.default_sender = email.utils.formataddr((email_account.name, email_account.get("email_id"))) - frappe.local.outgoing_email_account[append_to or "default"] = email_account + frappe.local.outgoing_email_account[append_to or sender_email_id or "default"] = email_account - return frappe.local.outgoing_email_account[append_to or "default"] + return frappe.local.outgoing_email_account[append_to or sender_email_id or "default"] def get_default_outgoing_email_account(raise_exception_not_set=True): '''conf should be like: @@ -136,8 +146,8 @@ class SMTPServer: else: self.setup_email_account(append_to) - def setup_email_account(self, append_to=None): - self.email_account = get_outgoing_email_account(raise_exception_not_set=False, append_to=append_to) + def setup_email_account(self, append_to=None, sender=None): + self.email_account = get_outgoing_email_account(raise_exception_not_set=False, append_to=append_to, sender=sender) if self.email_account: self.server = self.email_account.smtp_server self.login = getattr(self.email_account, "login_id", None) or self.email_account.email_id