pythonerpnextfrappe

How to attach a print format to attachments upon saving the Doctype in ERPNext?


I have created a custom print format in ErpNext from the Quotation Doctype.

It gets printed and I can download it as a PDF as well.

Now what I want is that whenever I save the Quotation Doctype, the PDF of that print format is named Scope of Work to attach in the attachments of Quotations (in the leftside bar of quotation).

Why I am doing this is because when I send the quotation in the email, I download the PDF manually when I print it and attach it to the email attachments so it is quite a hectic process, everytime I have to download the PDF and then attach it to the email attachments.

Now, that print format will be attached to attachments upon saving the Quotation, and when I send the email that attachment from quotation will automatically be attached to email attachments, which is what I want.

I was trying a custom script, but that did not work as expected, so I don't know may if there is any good way to achieve this.

Scope of Work is not my default print format, there are other formats I want to attach, like “Scope of Work Arabic”, another print format.

I need a script or function, or whatever, even a custom button will do the job do that when I click it, the formats will be attached to the attachments to doctype it, in this case the Quotation.

My bench version is 14.


Solution

  • I have solved it by writing a function in quotation.py like below.

    def attach_scope_of_work_to_attachments(doc, print_format, pdf_name):
        try:
            pdf_content = frappe.get_print(doc.doctype, doc.name, print_format, as_pdf=True)
            
            file_name = f"{doc.name}_{pdf_name}.pdf"
            
            existing_files = frappe.get_all("File",
            filters={
                "attached_to_doctype": doc.doctype,
                "attached_to_name": doc.name,
                "file_name": file_name
            },fields=["name"])
            
            if existing_files:
                for file_doc in existing_files:
                    frappe.delete_doc("File", file_doc.name, force=True)
    
            file_doc = frappe.get_doc({
                "doctype": "File",
                "file_name": file_name,
                "attached_to_doctype": doc.doctype,
                "attached_to_name": doc.name,
                "content": pdf_content,
                "is_private": 0
            })
    
    
            file_doc.save(ignore_permissions=True)
    
            doc.add_comment("Attachment", f"{file_doc.file_name} attached.")
            
            return True
        except Exception as e:
            frappe.throw(f"Error generating Scope of Work PDF: {str(e)}")
            return False
    

    and wrote another function after_insert like below

    def after_insert(self):
        self.attach_scope_of_work_to_attachments(print_format="Scope Of Work", pdf_name="scope_of_work")
        self.attach_scope_of_work_to_attachments(print_format="Scope Of Work Arabic", pdf_name="scope_of_work_arabic")