feat: allow more print page size options (develop)version-14
@@ -1523,8 +1523,8 @@ def format(*args, **kwargs): | |||||
import frappe.utils.formatters | import frappe.utils.formatters | ||||
return frappe.utils.formatters.format_value(*args, **kwargs) | return frappe.utils.formatters.format_value(*args, **kwargs) | ||||
def get_print(doctype=None, name=None, print_format=None, style=None, | |||||
html=None, as_pdf=False, doc=None, output=None, no_letterhead=0, password=None): | |||||
def get_print(doctype=None, name=None, print_format=None, style=None, html=None, | |||||
as_pdf=False, doc=None, output=None, no_letterhead=0, password=None, pdf_options=None): | |||||
"""Get Print Format for given document. | """Get Print Format for given document. | ||||
:param doctype: DocType of document. | :param doctype: DocType of document. | ||||
@@ -1543,15 +1543,15 @@ def get_print(doctype=None, name=None, print_format=None, style=None, | |||||
local.form_dict.doc = doc | local.form_dict.doc = doc | ||||
local.form_dict.no_letterhead = no_letterhead | local.form_dict.no_letterhead = no_letterhead | ||||
options = None | |||||
pdf_options = pdf_options or {} | |||||
if password: | if password: | ||||
options = {'password': password} | |||||
pdf_options['password'] = password | |||||
if not html: | if not html: | ||||
html = get_response_content("printview") | html = get_response_content("printview") | ||||
if as_pdf: | if as_pdf: | ||||
return get_pdf(html, output = output, options = options) | |||||
return get_pdf(html, options=pdf_options, output=output) | |||||
else: | else: | ||||
return html | return html | ||||
@@ -10,6 +10,8 @@ | |||||
"repeat_header_footer", | "repeat_header_footer", | ||||
"column_break_4", | "column_break_4", | ||||
"pdf_page_size", | "pdf_page_size", | ||||
"pdf_page_height", | |||||
"pdf_page_width", | |||||
"view_link_in_email", | "view_link_in_email", | ||||
"with_letterhead", | "with_letterhead", | ||||
"allow_print_for_draft", | "allow_print_for_draft", | ||||
@@ -56,7 +58,7 @@ | |||||
"fieldname": "pdf_page_size", | "fieldname": "pdf_page_size", | ||||
"fieldtype": "Select", | "fieldtype": "Select", | ||||
"label": "PDF Page Size", | "label": "PDF Page Size", | ||||
"options": "A4\nLetter" | |||||
"options": "A0\nA1\nA2\nA3\nA4\nA5\nA6\nA7\nA8\nA9\nB0\nB1\nB2\nB3\nB4\nB5\nB6\nB7\nB8\nB9\nB10\nC5E\nComm10E\nDLE\nExecutive\nFolio\nLedger\nLegal\nLetter\nTabloid\nCustom" | |||||
}, | }, | ||||
{ | { | ||||
"fieldname": "view_link_in_email", | "fieldname": "view_link_in_email", | ||||
@@ -156,6 +158,18 @@ | |||||
"fieldname": "font_size", | "fieldname": "font_size", | ||||
"fieldtype": "Float", | "fieldtype": "Float", | ||||
"label": "Font Size" | "label": "Font Size" | ||||
}, | |||||
{ | |||||
"depends_on": "eval:doc.pdf_page_size == \"Custom\"", | |||||
"fieldname": "pdf_page_height", | |||||
"fieldtype": "Float", | |||||
"label": "PDF Page Height (in mm)" | |||||
}, | |||||
{ | |||||
"depends_on": "eval:doc.pdf_page_size == \"Custom\"", | |||||
"fieldname": "pdf_page_width", | |||||
"fieldtype": "Float", | |||||
"label": "PDF Page Width (in mm)" | |||||
} | } | ||||
], | ], | ||||
"icon": "fa fa-cog", | "icon": "fa fa-cog", | ||||
@@ -8,14 +8,23 @@ from frappe.utils import cint | |||||
from frappe.model.document import Document | from frappe.model.document import Document | ||||
class PrintSettings(Document): | class PrintSettings(Document): | ||||
def validate(self): | |||||
if self.pdf_page_size == "Custom" and not ( | |||||
self.pdf_page_height and self.pdf_page_width | |||||
): | |||||
frappe.throw(_("Page height and width cannot be zero")) | |||||
def on_update(self): | def on_update(self): | ||||
frappe.clear_cache() | frappe.clear_cache() | ||||
@frappe.whitelist() | @frappe.whitelist() | ||||
def is_print_server_enabled(): | def is_print_server_enabled(): | ||||
if not hasattr(frappe.local, 'enable_print_server'): | |||||
frappe.local.enable_print_server = cint(frappe.db.get_single_value('Print Settings', | |||||
'enable_print_server')) | |||||
if not hasattr(frappe.local, "enable_print_server"): | |||||
frappe.local.enable_print_server = cint( | |||||
frappe.db.get_single_value("Print Settings", "enable_print_server") | |||||
) | |||||
return frappe.local.enable_print_server | return frappe.local.enable_print_server |
@@ -24,51 +24,84 @@ export default class BulkOperations { | |||||
return; | return; | ||||
} | } | ||||
if (valid_docs.length > 0) { | |||||
const dialog = new frappe.ui.Dialog({ | |||||
title: __('Print Documents'), | |||||
fields: [ | |||||
{ | |||||
'fieldtype': 'Select', | |||||
'label': __('Letter Head'), | |||||
'fieldname': 'letter_sel', | |||||
'default': __('No Letterhead'), | |||||
options: this.get_letterhead_options() | |||||
}, | |||||
{ | |||||
'fieldtype': 'Select', | |||||
'label': __('Print Format'), | |||||
'fieldname': 'print_sel', | |||||
options: frappe.meta.get_print_formats(this.doctype) | |||||
} | |||||
] | |||||
}); | |||||
if (valid_docs.length === 0) { | |||||
frappe.msgprint(__('Select atleast 1 record for printing')); | |||||
return; | |||||
} | |||||
const dialog = new frappe.ui.Dialog({ | |||||
title: __('Print Documents'), | |||||
fields: [{ | |||||
fieldtype: 'Select', | |||||
label: __('Letter Head'), | |||||
fieldname: 'letter_sel', | |||||
default: __('No Letterhead'), | |||||
options: this.get_letterhead_options() | |||||
}, | |||||
{ | |||||
fieldtype: 'Select', | |||||
label: __('Print Format'), | |||||
fieldname: 'print_sel', | |||||
options: frappe.meta.get_print_formats(this.doctype) | |||||
}, | |||||
{ | |||||
fieldtype: 'Select', | |||||
label: __('Page Size'), | |||||
fieldname: 'page_size', | |||||
options: frappe.meta.get_print_sizes(), | |||||
default: print_settings.pdf_page_size | |||||
}, | |||||
{ | |||||
fieldtype: 'Float', | |||||
label: __('Page Height (in mm)'), | |||||
fieldname: 'page_height', | |||||
depends_on: 'eval:doc.page_size == "Custom"', | |||||
default: print_settings.pdf_page_height | |||||
}, | |||||
{ | |||||
fieldtype: 'Float', | |||||
label: __('Page Width (in mm)'), | |||||
fieldname: 'page_width', | |||||
depends_on: 'eval:doc.page_size == "Custom"', | |||||
default: print_settings.pdf_page_width | |||||
}] | |||||
}); | |||||
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 json_string = JSON.stringify(valid_docs); | |||||
const letterhead = args.letter_sel; | |||||
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) | |||||
); | |||||
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 json_string = JSON.stringify(valid_docs); | |||||
const letterhead = args.letter_sel; | |||||
if (!w) { | |||||
frappe.msgprint(__('Please enable pop-ups')); | |||||
return; | |||||
let pdf_options; | |||||
if (args.page_size === "Custom") { | |||||
if (args.page_height === 0 || args.page_width === 0) { | |||||
frappe.throw(__('Page height and width cannot be zero')); | |||||
} | } | ||||
}); | |||||
pdf_options = JSON.stringify({ "page-height": args.page_height, "page-width": args.page_width }); | |||||
} else { | |||||
pdf_options = JSON.stringify({ "page-size": args.page_size }); | |||||
} | |||||
dialog.show(); | |||||
} else { | |||||
frappe.msgprint(__('Select atleast 1 record for printing')); | |||||
} | |||||
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) | |||||
); | |||||
if (!w) { | |||||
frappe.msgprint(__('Please enable pop-ups')); | |||||
return; | |||||
} | |||||
}); | |||||
dialog.show(); | |||||
} | } | ||||
get_letterhead_options () { | get_letterhead_options () { | ||||
@@ -192,6 +192,15 @@ $.extend(frappe.meta, { | |||||
} | } | ||||
}, | }, | ||||
get_print_sizes: function() { | |||||
return [ | |||||
"A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7", "A8", "A9", | |||||
"B0", "B1", "B2", "B3", "B4", "B5", "B6", "B7", "B8", "B9", "B10", | |||||
"C5E", "Comm10E", "DLE", "Executive", "Folio", "Ledger", "Legal", | |||||
"Letter", "Tabloid", "Custom" | |||||
]; | |||||
}, | |||||
get_print_formats: function(doctype) { | get_print_formats: function(doctype) { | ||||
var print_format_list = ["Standard"]; | var print_format_list = ["Standard"]; | ||||
var default_print_format = locals.DocType[doctype].default_print_format; | var default_print_format = locals.DocType[doctype].default_print_format; | ||||
@@ -95,7 +95,7 @@ def prepare_options(html, options): | |||||
'quiet': None, | 'quiet': None, | ||||
# 'no-outline': None, | # 'no-outline': None, | ||||
'encoding': "UTF-8", | 'encoding': "UTF-8", | ||||
#'load-error-handling': 'ignore' | |||||
# 'load-error-handling': 'ignore' | |||||
}) | }) | ||||
if not options.get("margin-right"): | if not options.get("margin-right"): | ||||
@@ -111,8 +111,21 @@ def prepare_options(html, options): | |||||
options.update(get_cookie_options()) | options.update(get_cookie_options()) | ||||
# page size | # page size | ||||
if not options.get("page-size"): | |||||
options['page-size'] = frappe.db.get_single_value("Print Settings", "pdf_page_size") or "A4" | |||||
pdf_page_size = ( | |||||
options.get("page-size") | |||||
or frappe.db.get_single_value("Print Settings", "pdf_page_size") | |||||
or "A4" | |||||
) | |||||
if pdf_page_size == "Custom": | |||||
options["page-height"] = options.get("page-height") or frappe.db.get_single_value( | |||||
"Print Settings", "pdf_page_height" | |||||
) | |||||
options["page-width"] = options.get("page-width") or frappe.db.get_single_value( | |||||
"Print Settings", "pdf_page_width" | |||||
) | |||||
else: | |||||
options["page-size"] = pdf_page_size | |||||
return html, options | return html, options | ||||
@@ -11,7 +11,7 @@ base_template_path = "www/printview.html" | |||||
standard_format = "templates/print_formats/standard.html" | standard_format = "templates/print_formats/standard.html" | ||||
@frappe.whitelist() | @frappe.whitelist() | ||||
def download_multi_pdf(doctype, name, format=None, no_letterhead=0): | |||||
def download_multi_pdf(doctype, name, format=None, no_letterhead=False, options=None): | |||||
""" | """ | ||||
Concatenate multiple docs as PDF . | Concatenate multiple docs as PDF . | ||||
@@ -54,18 +54,21 @@ def download_multi_pdf(doctype, name, format=None, no_letterhead=0): | |||||
import json | import json | ||||
output = PdfFileWriter() | output = PdfFileWriter() | ||||
if isinstance(options, str): | |||||
options = json.loads(options) | |||||
if not isinstance(doctype, dict): | if not isinstance(doctype, dict): | ||||
result = json.loads(name) | result = json.loads(name) | ||||
# Concatenating pdf files | # Concatenating pdf files | ||||
for i, ss in enumerate(result): | for i, ss in enumerate(result): | ||||
output = frappe.get_print(doctype, ss, format, as_pdf = True, output = output, no_letterhead=no_letterhead) | |||||
output = frappe.get_print(doctype, ss, format, as_pdf=True, output=output, no_letterhead=no_letterhead, pdf_options=options) | |||||
frappe.local.response.filename = "{doctype}.pdf".format(doctype=doctype.replace(" ", "-").replace("/", "-")) | frappe.local.response.filename = "{doctype}.pdf".format(doctype=doctype.replace(" ", "-").replace("/", "-")) | ||||
else: | else: | ||||
for doctype_name in doctype: | for doctype_name in doctype: | ||||
for doc_name in doctype[doctype_name]: | for doc_name in doctype[doctype_name]: | ||||
try: | try: | ||||
output = frappe.get_print(doctype_name, doc_name, format, as_pdf = True, output = output, no_letterhead=no_letterhead) | |||||
output = frappe.get_print(doctype_name, doc_name, format, as_pdf=True, output=output, no_letterhead=no_letterhead, pdf_options=options) | |||||
except Exception: | except Exception: | ||||
frappe.log_error("Permission Error on doc {} of doctype {}".format(doc_name, doctype_name)) | frappe.log_error("Permission Error on doc {} of doctype {}".format(doc_name, doctype_name)) | ||||
frappe.local.response.filename = "{}.pdf".format(name) | frappe.local.response.filename = "{}.pdf".format(name) | ||||