Skip to content

Commit

Permalink
fix: update printing dependencies (#125)
Browse files Browse the repository at this point in the history
Co-authored-by: Rohan Bansal <rohan@agritheory.dev>
  • Loading branch information
Alchez and Rohan Bansal committed Jun 4, 2024
1 parent 7fd6960 commit 49530cf
Show file tree
Hide file tree
Showing 3 changed files with 190 additions and 181 deletions.
143 changes: 74 additions & 69 deletions beam/beam/doctype/beam_settings/beam_settings.json
Original file line number Diff line number Diff line change
@@ -1,71 +1,76 @@
{
"actions": [],
"allow_rename": 1,
"autoname": "field:company",
"creation": "2024-03-18 17:06:58.552999",
"doctype": "DocType",
"engine": "InnoDB",
"field_order": ["company", "enable_handling_units", "barcode_font_size"],
"fields": [
{
"fieldname": "company",
"fieldtype": "Link",
"in_list_view": 1,
"label": "Company",
"options": "Company",
"reqd": 1,
"set_only_once": 1,
"unique": 1
},
{
"default": "1",
"fieldname": "enable_handling_units",
"fieldtype": "Check",
"in_list_view": 1,
"label": "Enable Handling Units"
},
{
"fieldname": "barcode_font_size",
"fieldtype": "Int",
"label": "Barcode Font Size"
}
],
"index_web_pages_for_search": 1,
"links": [],
"modified": "2024-04-16 18:33:34.282664",
"modified_by": "Administrator",
"module": "BEAM",
"name": "BEAM Settings",
"naming_rule": "Expression (old style)",
"owner": "Administrator",
"permissions": [
{
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
"print": 1,
"read": 1,
"report": 1,
"role": "System Manager",
"share": 1,
"write": 1
},
{
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
"print": 1,
"read": 1,
"report": 1,
"role": "Stock Manager",
"share": 1,
"write": 1
}
],
"sort_field": "modified",
"sort_order": "DESC",
"states": [],
"track_changes": 1
"actions": [],
"allow_rename": 1,
"autoname": "field:company",
"creation": "2024-03-18 17:06:58.552999",
"doctype": "DocType",
"engine": "InnoDB",
"field_order": [
"company",
"enable_handling_units",
"barcode_font_size"
],
"fields": [
{
"fieldname": "company",
"fieldtype": "Link",
"in_list_view": 1,
"label": "Company",
"options": "Company",
"reqd": 1,
"set_only_once": 1,
"unique": 1
},
{
"default": "1",
"fieldname": "enable_handling_units",
"fieldtype": "Check",
"in_list_view": 1,
"label": "Enable Handling Units"
},
{
"default": "12",
"fieldname": "barcode_font_size",
"fieldtype": "Int",
"label": "Barcode Font Size"
}
],
"index_web_pages_for_search": 1,
"links": [],
"modified": "2024-05-29 01:43:57.177980",
"modified_by": "Administrator",
"module": "BEAM",
"name": "BEAM Settings",
"naming_rule": "Expression (old style)",
"owner": "Administrator",
"permissions": [
{
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
"print": 1,
"read": 1,
"report": 1,
"role": "System Manager",
"share": 1,
"write": 1
},
{
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
"print": 1,
"read": 1,
"report": 1,
"role": "Stock Manager",
"share": 1,
"write": 1
}
],
"sort_field": "modified",
"sort_order": "DESC",
"states": [],
"track_changes": 1
}
226 changes: 115 additions & 111 deletions beam/beam/printing.py
Original file line number Diff line number Diff line change
@@ -1,111 +1,115 @@
import datetime
import json
import os
from pathlib import Path

import frappe
from frappe.utils import get_bench_path, get_files_path, random_string
from frappe.utils.jinja import get_jinja_hooks
from frappe.utils.safe_exec import get_safe_globals
from jinja2 import DebugUndefined, Environment
from PyPDF2 import PdfFileWriter

try:
import cups
except Exception as e:
frappe.log_error(e, "CUPS is not installed on this server")


@frappe.whitelist()
def print_by_server(
doctype,
name,
printer_setting,
print_format=None,
doc=None,
no_letterhead=0,
file_path=None,
):
print_settings = frappe.get_doc("Network Printer Settings", printer_setting)
if isinstance(doc, str):
doc = frappe._dict(json.loads(doc))
if not print_format:
print_format = frappe.get_meta(doctype).get("default_print_format")
print_format = frappe.get_doc("Print Format", print_format)
try:
cups.setServer(print_settings.server_ip)
cups.setPort(print_settings.port)
conn = cups.Connection()
if print_format.raw_printing == 1:
output = ""
# using a custom jinja environment so we don't have to use frappe's formatting
e = Environment(undefined=DebugUndefined)
e.globals.update(get_safe_globals())
e.globals.update(get_jinja_hooks("methods"))
template = e.from_string(print_format.raw_commands)
output = template.render(doc=doc)
if not file_path:
# use this path for testing, it will be available from the public server with the file name
# file_path = f"{get_bench_path()}/sites{get_files_path()[1:]}/{name}{random_string(10).upper()}.txt"
# use this technique for production
file_path = os.path.join("/", "tmp", f"frappe-zpl-{frappe.generate_hash()}.txt")
Path(file_path).write_text(output)
else:
output = PdfFileWriter()
output = frappe.get_print(
doctype,
name,
print_format.name,
doc=doc,
no_letterhead=no_letterhead,
as_pdf=True,
output=output,
)
if not file_path:
file_path = os.path.join("/", "tmp", f"frappe-pdf-{frappe.generate_hash()}.pdf")
output.write(open(file_path, "wb"))
conn.printFile(print_settings.printer_name, file_path, name, {})
frappe.msgprint(
f"{name } printing on {print_settings.printer_name}", alert=True, indicator="green"
)
except OSError as e:
if (
"ContentNotFoundError" in e.message
or "ContentOperationNotPermittedError" in e.message
or "UnknownContentError" in e.message
or "RemoteHostClosedError" in e.message
):
frappe.throw(frappe._("PDF generation failed"))
except cups.IPPError:
frappe.throw(frappe._("Printing failed"))


@frappe.whitelist()
def print_handling_units(
doctype=None, name=None, printer_setting=None, print_format=None, doc=None
):
if isinstance(doc, str):
doc = frappe._dict(json.loads(doc))

for row in doc.get("items"):
if not row.get("handling_unit"):
continue
# only print output / scrap items from Stock Entry
if doctype == "Stock Entry" and not row.get("t_warehouse"):
continue
# if one of the transfer types, use the 'to_handling_unit' field instead
if doctype == "Stock Entry" and doc.get("purpose") in (
"Material Transfer",
"Send to Subcontractor",
"Material Transfer for Manufacture",
):
handling_unit = frappe.get_doc("Handling Unit", row.get("to_handling_unit"))
else:
handling_unit = frappe.get_doc("Handling Unit", row.get("handling_unit"))
print_by_server(
handling_unit.doctype,
handling_unit.name,
printer_setting,
print_format,
handling_unit,
)
import json
import os
from pathlib import Path

import frappe

# from frappe.utils import get_bench_path, get_files_path, random_string
from frappe.utils.jinja import get_jinja_hooks
from frappe.utils.safe_exec import get_safe_globals

# Frappe dependencies
from jinja2 import DebugUndefined, Environment
from pypdf import PdfWriter

try:
import cups
except Exception as e:
frappe.log_error(e, "CUPS is not installed on this server")


@frappe.whitelist()
def print_by_server(
doctype,
name,
printer_setting,
print_format=None,
doc=None,
no_letterhead=0,
file_path=None,
):
print_settings = frappe.get_doc("Network Printer Settings", printer_setting)
if isinstance(doc, str):
doc = frappe._dict(json.loads(doc))
if not print_format:
print_format = frappe.get_meta(doctype).get("default_print_format")
print_format = frappe.get_doc("Print Format", print_format)
try:
cups.setServer(print_settings.server_ip)
cups.setPort(print_settings.port)
conn = cups.Connection()
if print_format.raw_printing == 1:
output = ""
# using a custom jinja environment so we don't have to use frappe's formatting
methods, filters = get_jinja_hooks()
e = Environment(undefined=DebugUndefined)
e.globals.update(get_safe_globals())
if methods:
e.globals.update(methods)
template = e.from_string(print_format.raw_commands)
output = template.render(doc=doc)
if not file_path:
# use this path for testing, it will be available from the public server with the file name
# file_path = f"{get_bench_path()}/sites{get_files_path()[1:]}/{name}{random_string(10).upper()}.txt"
# use this technique for production
file_path = os.path.join("/", "tmp", f"frappe-zpl-{frappe.generate_hash()}.txt")
Path(file_path).write_text(output)
else:
output = PdfWriter()
output = frappe.get_print(
doctype,
name,
print_format.name,
doc=doc,
no_letterhead=no_letterhead,
as_pdf=True,
output=output,
)
if not file_path:
file_path = os.path.join("/", "tmp", f"frappe-pdf-{frappe.generate_hash()}.pdf")
output.write(open(file_path, "wb"))
conn.printFile(print_settings.printer_name, file_path, name, {})
frappe.msgprint(
f"{name } printing on {print_settings.printer_name}", alert=True, indicator="green"
)
except OSError as e:
if (
"ContentNotFoundError" in e.message
or "ContentOperationNotPermittedError" in e.message
or "UnknownContentError" in e.message
or "RemoteHostClosedError" in e.message
):
frappe.throw(frappe._("PDF generation failed"))
except cups.IPPError:
frappe.throw(frappe._("Printing failed"))


@frappe.whitelist()
def print_handling_units(
doctype=None, name=None, printer_setting=None, print_format=None, doc=None
):
if isinstance(doc, str):
doc = frappe._dict(json.loads(doc))

for row in doc.get("items"):
if not row.get("handling_unit"):
continue
# only print output / scrap items from Stock Entry
if doctype == "Stock Entry" and not row.get("t_warehouse"):
continue
# if one of the transfer types, use the 'to_handling_unit' field instead
if doctype == "Stock Entry" and doc.get("purpose") in (
"Material Transfer",
"Send to Subcontractor",
"Material Transfer for Manufacture",
):
handling_unit = frappe.get_doc("Handling Unit", row.get("to_handling_unit"))
else:
handling_unit = frappe.get_doc("Handling Unit", row.get("handling_unit"))
print_by_server(
handling_unit.doctype,
handling_unit.name,
printer_setting,
print_format,
handling_unit,
)
2 changes: 1 addition & 1 deletion beam/customize.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ def load_customizations():
custom_field.flags.ignore_version = True
custom_field.save()
for prop in customizations.get("property_setters"):
if field.get("module") != "BEAM":
if prop.get("module") != "BEAM":
continue
property_setter = frappe.get_doc(
{
Expand Down

0 comments on commit 49530cf

Please sign in to comment.