From 4504bc1ebca13cd342604e489298bb28232b16cc Mon Sep 17 00:00:00 2001 From: Ameya Shenoy Date: Mon, 20 Aug 2018 13:08:40 +0530 Subject: [PATCH 1/3] [feature] print multiple docs from multiple doctypes --- frappe/utils/print_format.py | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/frappe/utils/print_format.py b/frappe/utils/print_format.py index 652b8804ab..2b555a03d8 100644 --- a/frappe/utils/print_format.py +++ b/frappe/utils/print_format.py @@ -20,14 +20,21 @@ def download_multi_pdf(doctype, name, format=None): # name can include names of many docs of the same doctype. import json - result = json.loads(name) - - # Concatenating pdf files output = PdfFileWriter() - for i, ss in enumerate(result): - output = frappe.get_print(doctype, ss, format, as_pdf = True, output = output) - frappe.local.response.filename = "{doctype}.pdf".format(doctype=doctype.replace(" ", "-").replace("/", "-")) + if not isinstance(doctype, dict): + result = json.loads(name) + + # Concatenating pdf files + for _, ss in enumerate(result): + output = frappe.get_print(doctype, ss, format, as_pdf = True, output = output) + frappe.local.response.filename = "{doctype}.pdf".format(doctype=doctype.replace(" ", "-").replace("/", "-")) + else: + for doctype_name in doctype: + for doc_name in doctype[doctype_name]: + output = frappe.get_print(doctype_name, doc_name, format, as_pdf = True, output = output) + frappe.local.response.filename = "{}.pdf".format(frappe.session.user.replace('@', '-')) + frappe.local.response.filecontent = read_multi_pdf(output) frappe.local.response.type = "download" From 65e96ff7a4a90b6440a6476fe946d08a75677f8e Mon Sep 17 00:00:00 2001 From: Ameya Shenoy Date: Tue, 21 Aug 2018 14:59:47 +0530 Subject: [PATCH 2/3] added docstring to download multi pdf - also made the PDF name as a parameter which is passed by the user --- frappe/utils/print_format.py | 41 ++++++++++++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/frappe/utils/print_format.py b/frappe/utils/print_format.py index 2b555a03d8..563508923b 100644 --- a/frappe/utils/print_format.py +++ b/frappe/utils/print_format.py @@ -17,7 +17,44 @@ standard_format = "templates/print_formats/standard.html" @frappe.whitelist() def download_multi_pdf(doctype, name, format=None): - # name can include names of many docs of the same doctype. + """ + Concatenate multiple docs as PDF . + + Returns a PDF compiled by concatenating multiple documents. The documents + can be from a single DocType or multiple DocTypes + + Note: The design may seem a little weird, but it exists exists to + ensure backward compatibility. The correct way to use this function is to + pass a dict to doctype as described below + + NEW FUNCTIONALITY + ================= + Parameters: + doctype (dict): + key (string): DocType name + value (list): of strings of doc names which need to be concatenated and printed + name (string): + name of the pdf which is generated + format: + Print Format to be used + + Returns: + PDF: A PDF generated by the concatenation of the mentioned input docs + + OLD FUNCTIONALITY - soon to be deprecated + ========================================= + Parameters: + doctype (string): + name of the DocType to which the docs belong which need to be printed + name (string or list): + If string the name of the doc which needs to be printed + If list the list of strings of doc names which needs to be printed + format: + Print Format to be used + + Returns: + PDF: A PDF generated by the concatenation of the mentioned input docs + """ import json output = PdfFileWriter() @@ -33,7 +70,7 @@ def download_multi_pdf(doctype, name, format=None): for doctype_name in doctype: for doc_name in doctype[doctype_name]: output = frappe.get_print(doctype_name, doc_name, format, as_pdf = True, output = output) - frappe.local.response.filename = "{}.pdf".format(frappe.session.user.replace('@', '-')) + frappe.local.response.filename = "{}.pdf".format(name) frappe.local.response.filecontent = read_multi_pdf(output) frappe.local.response.type = "download" From 8776376c13dccdf5bd17bca56702395fb56aa538 Mon Sep 17 00:00:00 2001 From: Ameya Shenoy Date: Thu, 23 Aug 2018 10:47:01 +0000 Subject: [PATCH 3/3] multi fixes - [fix] removed _ as a variable since it is used in translations - linting fixes - added error logging for permission errors --- frappe/utils/print_format.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/frappe/utils/print_format.py b/frappe/utils/print_format.py index 563508923b..ca6ff8c2d3 100644 --- a/frappe/utils/print_format.py +++ b/frappe/utils/print_format.py @@ -19,13 +19,13 @@ standard_format = "templates/print_formats/standard.html" def download_multi_pdf(doctype, name, format=None): """ Concatenate multiple docs as PDF . - + Returns a PDF compiled by concatenating multiple documents. The documents can be from a single DocType or multiple DocTypes Note: The design may seem a little weird, but it exists exists to ensure backward compatibility. The correct way to use this function is to - pass a dict to doctype as described below + pass a dict to doctype as described below NEW FUNCTIONALITY ================= @@ -63,13 +63,16 @@ def download_multi_pdf(doctype, name, format=None): result = json.loads(name) # Concatenating pdf files - for _, ss in enumerate(result): + for i, ss in enumerate(result): output = frappe.get_print(doctype, ss, format, as_pdf = True, output = output) frappe.local.response.filename = "{doctype}.pdf".format(doctype=doctype.replace(" ", "-").replace("/", "-")) else: for doctype_name in doctype: for doc_name in doctype[doctype_name]: - output = frappe.get_print(doctype_name, doc_name, format, as_pdf = True, output = output) + try: + output = frappe.get_print(doctype_name, doc_name, format, as_pdf = True, output = output) + except Exception: + frappe.log_error("Permission Error on doc {} of doctype {}".format(doc_name, doctype_name)) frappe.local.response.filename = "{}.pdf".format(name) frappe.local.response.filecontent = read_multi_pdf(output)