feat: move bulk print operation to the background
Signed-off-by: Akhil Narang <me@akhilnarang.dev>
This commit is contained in:
parent
a01085ddcc
commit
bf6cb1a49f
2 changed files with 90 additions and 43 deletions
|
|
@ -35,11 +35,6 @@ export default class BulkOperations {
|
|||
return;
|
||||
}
|
||||
|
||||
if (valid_docs.length > 50) {
|
||||
frappe.msgprint(__("You can only print upto 50 documents at a time"));
|
||||
return;
|
||||
}
|
||||
|
||||
const dialog = new frappe.ui.Dialog({
|
||||
title: __("Print Documents"),
|
||||
fields: [
|
||||
|
|
@ -102,28 +97,25 @@ export default class BulkOperations {
|
|||
pdf_options = JSON.stringify({ "page-size": args.page_size });
|
||||
}
|
||||
|
||||
const w = window.open(
|
||||
"/api/method/frappe.utils.print_format.download_multi_pdf?" +
|
||||
"doctype=" +
|
||||
encodeURIComponent(this.doctype) +
|
||||
"&name=" +
|
||||
encodeURIComponent(json_string) +
|
||||
"&format=" +
|
||||
encodeURIComponent(print_format) +
|
||||
"&no_letterhead=" +
|
||||
(with_letterhead ? "0" : "1") +
|
||||
"&letterhead=" +
|
||||
encodeURIComponent(letterhead) +
|
||||
"&options=" +
|
||||
encodeURIComponent(pdf_options)
|
||||
);
|
||||
const task_id = Math.random().toString(36).slice(-5);
|
||||
frappe.realtime.task_subscribe(task_id);
|
||||
frappe.realtime.on(`task_progress:${task_id}`, (data) => {
|
||||
frappe.msgprint(
|
||||
`Please click <a href=${data.file_url}>here</a> to download the PDF`
|
||||
);
|
||||
});
|
||||
|
||||
if (!w) {
|
||||
frappe.msgprint(__("Please enable pop-ups"));
|
||||
return;
|
||||
}
|
||||
frappe.call("frappe.utils.print_format.download_multi_pdf", {
|
||||
doctype: this.doctype,
|
||||
name: json_string,
|
||||
format: print_format,
|
||||
no_letterhead: with_letterhead ? "0" : "1",
|
||||
letterhead: letterhead,
|
||||
options: pdf_options,
|
||||
task_id: task_id,
|
||||
});
|
||||
dialog.hide();
|
||||
});
|
||||
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,35 @@ from frappe.www.printview import validate_print_permission
|
|||
|
||||
|
||||
@frappe.whitelist()
|
||||
def download_multi_pdf(doctype, name, format=None, no_letterhead=False, letterhead=None, options=None):
|
||||
def download_multi_pdf(
|
||||
doctype,
|
||||
name,
|
||||
format=None,
|
||||
no_letterhead=False,
|
||||
letterhead=None,
|
||||
options=None,
|
||||
task_id=None,
|
||||
):
|
||||
"""
|
||||
Calls _download_multi_pdf with the given parameters and returns the URL of the generated PDF
|
||||
|
||||
"""
|
||||
frappe.enqueue(
|
||||
_download_multi_pdf,
|
||||
doctype=doctype,
|
||||
name=name,
|
||||
format=format,
|
||||
no_letterhead=no_letterhead,
|
||||
letterhead=letterhead,
|
||||
options=options,
|
||||
task_id=task_id,
|
||||
)
|
||||
frappe.local.response["http_status_code"] = 201
|
||||
|
||||
|
||||
def _download_multi_pdf(
|
||||
doctype, name, format=None, no_letterhead=False, letterhead=None, options=None, task_id=None
|
||||
):
|
||||
"""Return a PDF compiled by concatenating multiple documents.
|
||||
|
||||
The documents can be from a single DocType or multiple DocTypes.
|
||||
|
|
@ -52,6 +80,7 @@ def download_multi_pdf(doctype, name, format=None, no_letterhead=False, letterhe
|
|||
|
||||
Returns:
|
||||
PDF: A PDF generated by the concatenation of the mentioned input docs
|
||||
|
||||
"""
|
||||
|
||||
import json
|
||||
|
|
@ -63,23 +92,35 @@ def download_multi_pdf(doctype, name, format=None, no_letterhead=False, letterhe
|
|||
|
||||
if not isinstance(doctype, dict):
|
||||
result = json.loads(name)
|
||||
total_docs = len(result)
|
||||
|
||||
# Concatenating pdf files
|
||||
for ss in result:
|
||||
pdf_writer = frappe.get_print(
|
||||
doctype,
|
||||
ss,
|
||||
format,
|
||||
as_pdf=True,
|
||||
output=pdf_writer,
|
||||
no_letterhead=no_letterhead,
|
||||
letterhead=letterhead,
|
||||
pdf_options=options,
|
||||
for idx, ss in enumerate(result):
|
||||
try:
|
||||
pdf_writer = frappe.get_print(
|
||||
doctype,
|
||||
ss,
|
||||
format,
|
||||
as_pdf=True,
|
||||
output=pdf_writer,
|
||||
no_letterhead=no_letterhead,
|
||||
letterhead=letterhead,
|
||||
pdf_options=options,
|
||||
)
|
||||
except Exception:
|
||||
frappe.publish_realtime(task_id=task_id, message={"message": "Failed"})
|
||||
|
||||
# Publish progress
|
||||
frappe.publish_progress(
|
||||
percent=(idx + 1) / total_docs * 100,
|
||||
title="Creating PDF",
|
||||
description=f"{idx+1} out of {total_docs}",
|
||||
task_id=task_id,
|
||||
)
|
||||
frappe.local.response.filename = "{doctype}.pdf".format(
|
||||
doctype=doctype.replace(" ", "-").replace("/", "-")
|
||||
)
|
||||
|
||||
else:
|
||||
total_docs = sum([len(doctype[dt]) for dt in doctype])
|
||||
count = 1
|
||||
for doctype_name in doctype:
|
||||
for doc_name in doctype[doctype_name]:
|
||||
try:
|
||||
|
|
@ -94,19 +135,33 @@ def download_multi_pdf(doctype, name, format=None, no_letterhead=False, letterhe
|
|||
pdf_options=options,
|
||||
)
|
||||
except Exception:
|
||||
frappe.publish_realtime(task_id=task_id, message="Failed")
|
||||
frappe.log_error(
|
||||
title="Error in Multi PDF download",
|
||||
message=f"Permission Error on doc {doc_name} of doctype {doctype_name}",
|
||||
reference_doctype=doctype_name,
|
||||
reference_name=doc_name,
|
||||
)
|
||||
frappe.local.response.filename = f"{name}.pdf"
|
||||
count += 1
|
||||
frappe.publish_progress(
|
||||
percent=count / total_docs * 100,
|
||||
title="Creating PDF",
|
||||
description=f"{count} out of {total_docs}",
|
||||
task_id=task_id,
|
||||
)
|
||||
|
||||
with BytesIO() as merged_pdf:
|
||||
pdf_writer.write(merged_pdf)
|
||||
frappe.local.response.filecontent = merged_pdf.getvalue()
|
||||
|
||||
frappe.local.response.type = "pdf"
|
||||
_file = frappe.get_doc(
|
||||
{
|
||||
"doctype": "File",
|
||||
"file_name": f"{task_id}.pdf",
|
||||
"content": merged_pdf.getvalue(),
|
||||
"is_private": 1,
|
||||
}
|
||||
)
|
||||
_file.save()
|
||||
frappe.publish_realtime(f"task_progress:{task_id}", message={"file_url": _file.unique_url})
|
||||
|
||||
|
||||
@deprecated
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue