diff --git a/frappe/public/js/frappe/list/bulk_operations.js b/frappe/public/js/frappe/list/bulk_operations.js index 0fec4f346e..0b794a03c3 100644 --- a/frappe/public/js/frappe/list/bulk_operations.js +++ b/frappe/public/js/frappe/list/bulk_operations.js @@ -166,104 +166,6 @@ export default class BulkOperations { dialog.show(); } - consolidated_print(docs) { - const print_settings = frappe.model.get_doc(":Print Settings", "Print Settings"); - const allow_print_for_draft = cint(print_settings.allow_print_for_draft); - const is_submittable = frappe.model.is_submittable(this.doctype); - const allow_print_for_cancelled = cint(print_settings.allow_print_for_cancelled); - const letterheads = this.get_letterhead_options(); - const MAX_CONSOLIDATED_LIMIT = 100; - - const valid_docs = docs - .filter((doc) => { - return ( - !is_submittable || - doc.docstatus === 1 || - (allow_print_for_cancelled && doc.docstatus == 2) || - (allow_print_for_draft && doc.docstatus == 0) || - frappe.user.has_role("Administrator") - ); - }) - .map((doc) => doc.name); - - const invalid_docs = docs.filter((doc) => !valid_docs.includes(doc.name)); - - if (invalid_docs.length > 0) { - frappe.msgprint(__("You selected Draft or Cancelled documents")); - return; - } - - if (valid_docs.length === 0) { - frappe.msgprint(__("Select atleast 1 record for printing")); - return; - } - - if (valid_docs.length > MAX_CONSOLIDATED_LIMIT) { - frappe.msgprint( - __("You can only consolidate up to {0} documents at a time", [ - MAX_CONSOLIDATED_LIMIT, - ]) - ); - return; - } - - const dialog = new frappe.ui.Dialog({ - title: __("Consolidated Print"), - fields: [ - { - fieldtype: "HTML", - options: `

${__( - "All selected documents will be rendered in a single continuous layout without page breaks between them." - )}

`, - }, - { - fieldtype: "Select", - label: __("Letter Head"), - fieldname: "letter_sel", - options: letterheads, - default: letterheads[0], - }, - { - fieldtype: "Select", - label: __("Print Format"), - fieldname: "print_sel", - options: frappe.meta.get_print_formats(this.doctype), - default: frappe.get_meta(this.doctype).default_print_format, - }, - ], - }); - - dialog.set_primary_action(__("Print"), (args) => { - if (!args) return; - const default_print_format = frappe.get_meta(this.doctype).default_print_format; - const with_letterhead = args.letter_sel == __("No Letterhead") ? 0 : 1; - const print_format = args.print_sel ? args.print_sel : default_print_format; - const names_json = JSON.stringify(valid_docs); - const letterhead = args.letter_sel; - - const w = window.open( - "/consolidated_printview?" + - "doctype=" + - encodeURIComponent(this.doctype) + - "&names=" + - encodeURIComponent(names_json) + - "&format=" + - encodeURIComponent(print_format) + - "&no_letterhead=" + - (with_letterhead ? "0" : "1") + - "&letterhead=" + - encodeURIComponent(letterhead) + - "&trigger_print=1" - ); - - if (!w) { - frappe.msgprint(__("Please enable pop-ups")); - } - dialog.hide(); - }); - dialog.show(); - } - get_letterhead_options() { const letterhead_options = [__("No Letterhead")]; frappe.call({ diff --git a/frappe/public/js/frappe/list/list_view.js b/frappe/public/js/frappe/list/list_view.js index a34b28ac57..2c28a24063 100644 --- a/frappe/public/js/frappe/list/list_view.js +++ b/frappe/public/js/frappe/list/list_view.js @@ -2279,14 +2279,6 @@ frappe.views.ListView = class ListView extends frappe.views.BaseList { }; }; - const bulk_consolidated_printing = () => { - return { - label: __("Consolidated Print", null, "Button in list view actions menu"), - action: () => bulk_operations.consolidated_print(this.get_checked_items()), - standard: true, - }; - }; - const bulk_delete = () => { return { label: __("Delete", null, "Button in list view actions menu"), @@ -2577,7 +2569,6 @@ frappe.views.ListView = class ListView extends frappe.views.BaseList { // bulk printing if (frappe.model.can_print(doctype)) { actions_menu_items.push(bulk_printing()); - actions_menu_items.push(bulk_consolidated_printing()); } // bulk submit diff --git a/frappe/www/consolidated_printview.html b/frappe/www/consolidated_printview.html deleted file mode 100644 index e75c3343a3..0000000000 --- a/frappe/www/consolidated_printview.html +++ /dev/null @@ -1,81 +0,0 @@ - - - - - - {{ title }} - - {{ include_style('print.bundle.css') }} - {% if print_style %} - - {% endif %} - - - - - - - -{%- if doc_count -%} - -{%- endif -%} - diff --git a/frappe/www/consolidated_printview.py b/frappe/www/consolidated_printview.py deleted file mode 100644 index 85d84fb1cd..0000000000 --- a/frappe/www/consolidated_printview.py +++ /dev/null @@ -1,118 +0,0 @@ -# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors -# License: MIT. See LICENSE - -import json - -import frappe -from frappe import _ -from frappe.core.doctype.access_log.access_log import make_access_log -from frappe.utils import cint -from frappe.utils.jinja_globals import is_rtl -from frappe.www.printview import ( - get_print_format_doc, - get_print_style, - get_rendered_template, - set_link_titles, - trigger_print_script, -) - -no_cache = 1 - -MAX_CONSOLIDATED_PRINT_DOCS = 100 - - -def get_context(context): - """Build context for consolidated (multi-document, no page-break) print.""" - doctype = frappe.form_dict.get("doctype") - names_json = frappe.form_dict.get("names") - - if not doctype or not names_json: - return { - "body": "

Error

Parameters doctype and names are required.

", - "print_style": "", - "title": "Error", - "lang": "en", - "layout_direction": "ltr", - "doc_count": 0, - } - - try: - names = json.loads(names_json) - except (json.JSONDecodeError, TypeError): - frappe.throw(_("Invalid names parameter: must be a JSON array of document names")) - - if not isinstance(names, list) or len(names) == 0: - frappe.throw(_("At least one document name is required")) - - if len(names) > MAX_CONSOLIDATED_PRINT_DOCS: - frappe.throw( - _("Cannot consolidate more than {0} documents at a time").format(MAX_CONSOLIDATED_PRINT_DOCS) - ) - - format_name = frappe.form_dict.get("format") or None - no_letterhead = frappe.form_dict.get("no_letterhead", 0) - letterhead = frappe.form_dict.get("letterhead") or None - trigger_print = cint(frappe.form_dict.get("trigger_print", 0)) - - meta = frappe.get_meta(doctype) - print_format = get_print_format_doc(format_name, meta=meta) - - all_html_parts = [] - - for name in names: - try: - doc = frappe.get_lazy_doc(doctype, name) - set_link_titles(doc) - html = _get_doc_print_html(doc, print_format, meta, no_letterhead, letterhead) - all_html_parts.append(html) - except frappe.PermissionError: - frappe.log_error( - title="Consolidated Print Permission Error", - message=f"No permission to print {doctype} {name}", - ) - except Exception: - frappe.log_error( - title="Consolidated Print Render Error", - message=f"Error rendering {doctype} {name}", - ) - - separator = '' - body = separator.join(f'
{html}
' for html in all_html_parts) - - if trigger_print: - body += trigger_print_script - - make_access_log( - doctype=doctype, - document=", ".join(names[:10]), - file_type="PDF", - method="Print", - page=f"Consolidated Print Format: {getattr(print_format, 'name', 'Standard')} ({len(names)} docs)", - ) - - return { - "body": body, - "print_style": get_print_style(frappe.form_dict.get("style"), print_format), - "title": f"Consolidated Print — {doctype}", - "lang": frappe.local.lang, - "layout_direction": "rtl" if is_rtl() else "ltr", - "doctype": doctype, - "doc_count": len(all_html_parts), - } - - -def _get_doc_print_html(doc, print_format, meta, no_letterhead, letterhead): - """Return rendered HTML for a single document, handling both standard and beta print formats.""" - if print_format and print_format.get("print_format_builder_beta"): - from frappe.utils.weasyprint import get_html - - return get_html(doctype=doc.doctype, name=doc.name, print_format=print_format.name) - - return get_rendered_template( - doc=doc, - print_format=print_format, - meta=meta, - no_letterhead=no_letterhead, - letterhead=letterhead, - trigger_print=False, - )