Browse Source

Merge pull request #14577 from Alchez/dev-granular-printing

feat: allow more print page size options (develop)
version-14
mergify[bot] 3 years ago
committed by GitHub
parent
commit
17aa4b823b
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 137 additions and 56 deletions
  1. +5
    -5
      frappe/__init__.py
  2. +15
    -1
      frappe/printing/doctype/print_settings/print_settings.json
  3. +12
    -3
      frappe/printing/doctype/print_settings/print_settings.py
  4. +74
    -41
      frappe/public/js/frappe/list/bulk_operations.js
  5. +9
    -0
      frappe/public/js/frappe/model/meta.js
  6. +16
    -3
      frappe/utils/pdf.py
  7. +6
    -3
      frappe/utils/print_format.py

+ 5
- 5
frappe/__init__.py View File

@@ -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




+ 15
- 1
frappe/printing/doctype/print_settings/print_settings.json View File

@@ -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",


+ 12
- 3
frappe/printing/doctype/print_settings/print_settings.py View File

@@ -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

+ 74
- 41
frappe/public/js/frappe/list/bulk_operations.js View File

@@ -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 () {


+ 9
- 0
frappe/public/js/frappe/model/meta.js View File

@@ -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;


+ 16
- 3
frappe/utils/pdf.py View File

@@ -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




+ 6
- 3
frappe/utils/print_format.py View File

@@ -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)


Loading…
Cancel
Save