Require - Doctype's public accessible print pdf url

I need to share public sharable url for my doctype (example: Sales Invoice pdf file with my Print Format). I could get some hashed url ( email notification but I want to achieve the same in SMS notification text that can be shared with my Customers or Users.

Right now, {{ doc.geturl() }} in my SMS Notification template is giving output something like this which has restricted access

Thanks in advance.
Vinod Kumar K

That is what I use :

Exemple for delivery note


1 Like

Thanks Frederic. I ll give it a try

@VinodKumarkolli just give print permissions to Guest

Be careful with this. It is not a good solution in most situations, as guest users will be able to view all invoices from easily guessable URLs. @FredericVerville’s solution is much more secure.

@peterg not if you are good at coding and you can encrypt the name

I don’t follow you. These are URLs, derived from naming series. You can’t encrypt them if you want them to work.

Giving guests print permission is a bad practice.

1 Like

@peterg you can do anything you want if you are good enough at coding . in my case I encrypted the sales invoice name to something like “mlsdkfiekjsbnwbczidqsjocvpoxcqnaizdlqsdazeqlskjlazelkjakjqslqjd=” using python encrypt and changed the download pdf function to decrypt the code before generating pdf. this way you cant guess any other sales invoice name .

This is not a good practice or good advice.


I implemented this by creating a custom field link_code on the doctype you need to print.

create a hook for an after_insert on the doctype to populate the link code

def create_payment_link_code(doc, method=None):
    doc.link_code = frappe.generate_hash(length=56) +"-")[-1]

I did not take any chances on duplicate link_codes being created I concated the doc name series to ensure their uniqueness.

I then create the following whitelisted method. Note the ignore_permission flag to ensure that no permissions are checked.

def download_receipt(ref):
    payment_name = frappe.get_all("Payment Entry", filters={"link_code": ref}, fields=["name"])[0]
    doc = frappe.get_doc("Payment Entry",
    doc.flags.ignore_permissions = 1
    with print_language(None):
        pdf_file = frappe.get_print(
            "Payment Entry",,  doc=doc, as_pdf=True, letterhead=None, no_letterhead=1

    frappe.local.response.filename = "{name}.pdf".format(" ", "-").replace("/", "-")
    frappe.local.response.filecontent = pdf_file
    frappe.local.response.type = "pdf"

Call the method with the unique link_code to generate the pdf