Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion frappe/printing/page/print/print.js
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,13 @@ frappe.ui.form.PrintView = class {
this.sidebar_dynamic_section = $(`<div class="dynamic-settings"></div>`).appendTo(
this.sidebar
);

this.ncr_selector = this.add_sidebar_item({
fieldtype: "Check",
fieldname: "ncr_check",
label: __("NCR"),
default:0
});
}

add_sidebar_item(df, is_dynamic) {
Expand Down Expand Up @@ -665,7 +672,9 @@ frappe.ui.form.PrintView = class {
encodeURIComponent(this.get_letterhead()) +
"&settings=" +
encodeURIComponent(JSON.stringify(this.additional_settings)) +
(this.lang_code ? "&_lang=" + this.lang_code : "")
(this.lang_code ? "&_lang=" + this.lang_code : "") +
"&ncr=" +
encodeURIComponent(this.is_ncr())
)
);
if (!w) {
Expand Down Expand Up @@ -762,6 +771,10 @@ frappe.ui.form.PrintView = class {
return this.print_format_selector.val() || "Standard";
}

is_ncr() {
return this.ncr_selector.value;
}

is_raw_printing(format) {
return this.get_print_format(format).raw_printing === 1;
}
Expand Down
14 changes: 12 additions & 2 deletions frappe/public/js/frappe/list/bulk_operations.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,20 +82,27 @@ export default class BulkOperations {
depends_on: 'eval:doc.page_size == "Custom"',
default: print_settings.pdf_page_width,
},
{
fieldtype: "Check",
label: __("NCR"),
fieldname: "ncr_check",
default: 0
},
{
fieldtype: "Check",
label: __("Background Print (required for >25 documents)"),
fieldname: "background_print",
default: valid_docs.length > BACKGROUND_PRINT_THRESHOLD,
read_only: valid_docs.length > BACKGROUND_PRINT_THRESHOLD,
},
}
],
});

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 ncr_selector = args.ncr_check;
const print_format = args.print_sel ? args.print_sel : default_print_format;
const json_string = JSON.stringify(valid_docs);
const letterhead = args.letter_sel;
Expand All @@ -122,6 +129,7 @@ export default class BulkOperations {
no_letterhead: with_letterhead ? "0" : "1",
letterhead: letterhead,
options: pdf_options,
ncr:ncr_selector
})
.then((response) => {
let task_id = response.message.task_id;
Expand Down Expand Up @@ -154,7 +162,9 @@ export default class BulkOperations {
"&letterhead=" +
encodeURIComponent(letterhead) +
"&options=" +
encodeURIComponent(pdf_options)
encodeURIComponent(pdf_options) +
"&ncr=" +
encodeURIComponent(ncr_selector)
);

if (!w) {
Expand Down
63 changes: 58 additions & 5 deletions frappe/utils/print_format.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,18 @@
import uuid
from io import BytesIO
from typing import Literal
from reportlab.pdfgen import canvas

from pypdf import PdfWriter

from pypdf import PdfReader, PdfWriter

import frappe
from frappe import _
from frappe.core.doctype.access_log.access_log import make_access_log
from frappe.translate import print_language
from frappe.utils.deprecations import deprecated
from frappe.utils.pdf import get_pdf
from .print_utils import ncr_get_print, add_background_color, merge_pdfs

no_cache = 1

Expand All @@ -30,11 +33,12 @@ def download_multi_pdf(
no_letterhead: bool = False,
letterhead: str | None = None,
options: str | None = None,
ncr: bool = False,
):
"""
Calls _download_multi_pdf with the given parameters and returns the response
"""
return _download_multi_pdf(doctype, name, format, no_letterhead, letterhead, options)
return _download_multi_pdf(doctype, name, format, no_letterhead, letterhead, options, ncr)


@frappe.whitelist()
Expand All @@ -45,6 +49,7 @@ def download_multi_pdf_async(
no_letterhead: bool = False,
letterhead: str | None = None,
options: str | None = None,
ncr: bool = False,
):
"""
Calls _download_multi_pdf with the given parameters in a background job, returns task ID
Expand All @@ -64,6 +69,7 @@ def download_multi_pdf_async(
no_letterhead=no_letterhead,
letterhead=letterhead,
options=options,
ncr=ncr,
queue="long" if doc_count > 20 else "short",
)
frappe.local.response["http_status_code"] = http.HTTPStatus.CREATED
Expand All @@ -77,6 +83,7 @@ def _download_multi_pdf(
no_letterhead: bool = False,
letterhead: str | None = None,
options: str | None = None,
ncr: bool = False,
task_id: str | None = None,
):
"""Return a PDF compiled by concatenating multiple documents.
Expand Down Expand Up @@ -118,6 +125,7 @@ def _download_multi_pdf(
filename = ""

pdf_writer = PdfWriter()
pdf_writer_ncr = PdfWriter()

if isinstance(options, str):
options = json.loads(options)
Expand All @@ -140,6 +148,18 @@ def _download_multi_pdf(
letterhead=letterhead,
pdf_options=options,
)
if ncr:
pdf_writer_ncr = ncr_get_print(
doctype,
ss,
format,
as_pdf=True,
output=pdf_writer_ncr,
letterhead=letterhead,
no_letterhead=no_letterhead,
pdf_options=options
)

except Exception:
if task_id:
frappe.publish_realtime(task_id=task_id, message={"message": "Failed"})
Expand Down Expand Up @@ -177,6 +197,17 @@ def _download_multi_pdf(
letterhead=letterhead,
pdf_options=options,
)
if ncr:
pdf_writer_ncr = ncr_get_print(
doctype,
doc_name,
format,
as_pdf=True,
output=pdf_writer_ncr,
letterhead=letterhead,
no_letterhead=no_letterhead,
pdf_options=options
)
except Exception:
if task_id:
frappe.publish_realtime(task_id=task_id, message="Failed")
Expand All @@ -201,21 +232,27 @@ def _download_multi_pdf(
if task_id is None:
frappe.local.response.filename = f"{name}.pdf"

with BytesIO() as merged_pdf:
with BytesIO() as merged_pdf, BytesIO() as merged_pdf_ncr:
pdf_writer.write(merged_pdf)
final_pdf = merged_pdf.getvalue()

if ncr:
pdf_writer_ncr.write(merged_pdf_ncr)
pdf_with_color = add_background_color(merged_pdf_ncr.getvalue())
final_pdf = merge_pdfs([merged_pdf.getvalue(), pdf_with_color])
if task_id:
_file = frappe.get_doc(
{
"doctype": "File",
"file_name": f"{filename}{task_id}.pdf",
"content": merged_pdf.getvalue(),
"content": final_pdf,
"is_private": 1,
}
)
_file.save()
frappe.publish_realtime(f"task_complete:{task_id}", message={"file_url": _file.unique_url})
else:
frappe.local.response.filecontent = merged_pdf.getvalue()
frappe.local.response.filecontent = final_pdf
frappe.local.response.type = "pdf"


Expand All @@ -236,6 +273,7 @@ def download_pdf(
language=None,
letterhead=None,
pdf_generator: Literal["wkhtmltopdf", "chrome"] | None = None,
ncr: bool = False,
):
doc = doc or frappe.get_doc(doctype, name)
validate_print_permission(doc)
Expand All @@ -251,6 +289,17 @@ def download_pdf(
no_letterhead=no_letterhead,
pdf_generator=pdf_generator,
)
if ncr:
pdf_file_2 = ncr_get_print(
doctype,
name,
format,
doc=doc,
as_pdf=True,
letterhead=letterhead,
no_letterhead=no_letterhead,
pdf_generator=pdf_generator,
)

title = doc.get_title()
if title and title == name:
Expand All @@ -260,6 +309,10 @@ def download_pdf(
title = title[:25]
title = title.rstrip()
title = " " + title

if ncr:
jut_list = [pdf_file, add_background_color(pdf_file_2)]
pdf_file = merge_pdfs(jut_list)

frappe.local.response.filename = "{name}{title}.pdf".format(
name=name.replace(" ", "-").replace("/", "-"),
Expand Down
Loading
Loading