[ Achieved ]Frappe.sendmail : Send email using scheduler with attachments

Hello Community,

I am working on scheduler task in which i want to sent an email on every sunday to the customer whose payment ( Sales Invoice ) are Overdue.

I have done with auto emailing, but how can i attach file in email ?

Like if Customer A has 4 Overdue Invoice then i want to attach all 4 invoice in single mail with template.

Hardik Gadesha

1 Like

“I have done with auto emailing, but how can i attach file in email”

Good question! You will need to study the existing code, to then develop what you require.

For eg there’s this function frappe/email_body.py at develop · frappe/frappe · GitHub

A search on ‘attach_file’ will give you pointers to learn from others?

1 Like

Thanks For your kind words @clarkej

I have achieved this feature :slight_smile:

1 Like

@Hardik_Gadesha sharing the steps may help fellow community developers


Yes Sure @hereabdulla

  1. Collect all Overdue Invoice which has status Overdue.
  2. Prepare Content for mail.
  3. Loop through all invoice and adjust all data in content.
  4. Fetch customer email id.
  5. Use frappe.sendmail to send mail.

I hope you got it. Will post detailed solution soon.


can you share the code of frappe.sendmail

def sendmail():
user_list = frappe.db.sql("""select name, employee_name from `tabEmployee` where designation = "Batch Supervisor";""")
for user_obj in user_list:
    user = user_obj[0];
    employee = user_obj[1];
    content = "<h4>Hello, "+ employee +"</h4><p>Following Batch will be expiry soon. Please make a note for that.</p><table class='table table-bordered'><tr><th>Batch Number</th><th>Expiry Date</th></tr>"
    batch_list = frappe.db.sql("""select batch_id, expiry_date  from `tabBatch` where DATEDIFF(expiry_date, CURRENT_DATE()) < 30;""")
    for batch_obj in batch_list:
        batch = batch_obj[0]
        expiry_date = str(batch_obj[1].strftime('%d/%m/%Y'))
        content = content + "<tr><td>"+batch+"</td><td>"+expiry_date+"</td></tr>"         
    content = content + "</table>"
    recipient = frappe.get_value("Employee", user, "prefered_email")
        subject="Item Batch To Be Expire", content=content)

do i have to import any package to use frappe.sendemail?

No. it’s just as it.

i have written this code in default python file which auto created on making of doctype.


Is that possible to send email to supplier on a particular date by custom code?
Now i can send mail by custom code using "“frappe.sendmail”.
I want it to be sent on particular date. (One day before Requested date).

you can use this script to get next day document and send email using this…

def getData():
		request_doc=frappe.get_all("Purchase Order",filters={"schedule_date":add_days(today(),1)},fields=["name"])
		return request_doc
		if request_doc:
			for doc in request_doc:
				po_doc=frappe.get_doc("Purchase Order",doc.name)
                            #write email send logic#

	except Exception as e:
		return generateResponse("F",error=e)

def getSupplierEmail(supplier):
	supplier_doc=frappe.get_all("Contact",filters=[["Dynamic Link","link_doctype","=","Supplier"],["Dynamic Link","link_name","=",supplier]],fields=["email_id"])
	return supplier_doc[0].email_id

also you can use email alert and set alert days before …


Hey @Maheshwari_Bhavesh

Thanks. this one works fine for me.

Now i am calling this function “getData():” from “Purchase order onload”,But i want to call it daily without that onload trigger function ,for that some guys has sugegsted me to use hook.py

Can some one help me to call this function( getData():slight_smile: daily from hook.py?

scheduler_events = {
	"daily": [
1 Like

i have called.the how to check that? Do i have to restart the bench?

how did you send email on every sunday? by scheduler?

Can you please share that code?

Use Cron Expression For This.

Use This Site to Genrate cron as per your requirment Crontab.guru - The cron schedule expression editor

1 Like

No attachment here though!

Check within the working erpnext code:
if receiver:
email_args = {
“recipients”: [receiver],
“message”: (message),
“subject”: ‘Salary Slip - from {0} to {1}’.format(self.start_date, self.end_date),
“attachments”: [frappe.attach_print(self.doctype, self.name, file_name=self.name, password=password)],
“reference_doctype”: self.doctype,
“reference_name”: self.name
if not frappe.flags.in_test:
enqueue(method=frappe.sendmail, queue=‘short’, timeout=300, is_async=True, **email_args)
(“{0}: Employee email not found, hence email not sent”).format(self.employee_name))

As I’m new to frappe can you please guide me where to write these custom scripts.
PS-Thanks in advance