Skip to content
Merged
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
53 changes: 52 additions & 1 deletion posnext/doc_events/item.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import frappe

from frappe import _
from frappe.utils.pdf import get_pdf
from frappe.www.printview import get_context
import json
from frappe.utils import now
from frappe.utils.file_manager import save_file

def validate_item(doc, method):
for x in doc.custom_items:
Expand Down Expand Up @@ -29,4 +34,50 @@ def get_product_bundle_with_items(item_code):
"name": bundle_doc.name,
"new_item_code": bundle_doc.new_item_code,
"items": bundle_items
}


@frappe.whitelist()
def print_barcodes(item_codes):
if isinstance(item_codes, str):

item_codes = json.loads(item_codes)


items_with_barcodes = [
frappe.get_doc("Item", code)
for code in item_codes
if frappe.get_doc("Item", code).barcodes
]

if not items_with_barcodes:
frappe.throw(_("No items with barcodes found"))

print_format = "Barcode Print"

if len(items_with_barcodes) == 1:
item_name = items_with_barcodes[0].name
url = f"/printview?doctype=Item&name={item_name}&format={print_format}&no_letterhead=1"
return {"url": url}

html_content = ''.join(
f'<div>{frappe.get_print("Item", item.name, print_format, doc=item)}</div>'
for item in items_with_barcodes
)

pdf_data = get_pdf(html_content)

file_name = f"Multiple_Barcodes_{now().replace(' ', '_').replace(':', '-')}.pdf"
file_doc = save_file(
fname=file_name,
content=pdf_data,
dt="Item",
dn=items_with_barcodes[0].name,
is_private=0
)

return {
"url": file_doc.file_url,
"message": _(f"Generated barcodes for {len(items_with_barcodes)} items."),
"is_pdf": True
}
2 changes: 1 addition & 1 deletion posnext/hooks.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
# include js in doctype views
doctype_js = {"POS Profile" : "public/js/pos_profile.js"}

# doctype_list_js = {"doctype" : "public/js/doctype_list.js"}
doctype_list_js = {"Item" : "public/js/item_list.js"}
# doctype_tree_js = {"doctype" : "public/js/doctype_tree.js"}
# doctype_calendar_js = {"doctype" : "public/js/doctype_calendar.js"}

Expand Down
Empty file.
Empty file.
31 changes: 31 additions & 0 deletions posnext/posnext/print_format/barcode_print/barcode_print.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"absolute_value": 0,
"align_labels_right": 0,
"creation": "2025-04-29 14:04:26.038617",
"custom_format": 1,
"default_print_language": "en-US",
"disabled": 0,
"doc_type": "Item",
"docstatus": 0,
"doctype": "Print Format",
"font_size": 14,
"html": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <title>Barcode Label</title>\n <style>\n body {\n font-family: Arial, sans-serif;\n padding: 20px;\n }\n .barcode-container {\n margin-bottom: 30px;\n page-break-inside: avoid;\n text-align: center;\n padding: 10px;\n border: 1px solid #eee;\n width: 200px;\n display: inline-block;\n margin-right: 10px;\n }\n .item-name {\n margin-bottom: 5px;\n font-weight: bold;\n }\n .barcode {\n margin-top: 10px;\n }\n .barcode-number {\n margin-top: 5px;\n font-size: 10px;\n }\n </style>\n</head>\n<body>\n\n <div class=\"barcode-container\">\n <div class=\"item-name\">\n {{ doc.item_name or doc.name }}\n </div>\n\n <div class=\"barcode\">\n {% set batch_id = frappe.db.get_value(\"Item Barcode\", {\"parent\": doc.name}, \"barcode\") %}\n <img src=\"https://barcode.tec-it.com/barcode.ashx?data={{ batch_id | urlencode if batch_id else 'N/A' }}&code=Code128&translate-esc\" width=\"160\" height=\"60\" alt=\"Barcode\">\n </div>\n\n \n </div>\n\n</body>\n</html>\n",
"idx": 0,
"line_breaks": 0,
"margin_bottom": 15.0,
"margin_left": 15.0,
"margin_right": 15.0,
"margin_top": 15.0,
"modified": "2025-04-29 14:51:39.357708",
"modified_by": "Administrator",
"module": "Posnext",
"name": "Barcode Print",
"owner": "Administrator",
"page_number": "Hide",
"print_format_builder": 0,
"print_format_builder_beta": 0,
"print_format_type": "Jinja",
"raw_printing": 0,
"show_section_headings": 0,
"standard": "Yes"
}
Empty file.
31 changes: 31 additions & 0 deletions posnext/posnext/print_format/print_barcodes/print_barcodes.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"absolute_value": 0,
"align_labels_right": 0,
"creation": "2025-04-29 11:29:57.511867",
"custom_format": 1,
"default_print_language": "en-US",
"disabled": 0,
"doc_type": "Item",
"docstatus": 0,
"doctype": "Print Format",
"font_size": 14,
"html": "<!DOCTYPE html>\n<html>\n<head>\n <title>Barcode Print</title>\n</head>\n<body>\n <h3>Barcode Print</h3>\n <table border=\"1\" cellpadding=\"10\">\n <thead>\n <tr>\n <th>Item Code</th>\n <th>Item Name</th>\n <th>Barcode</th>\n </tr>\n </thead>\n <tbody>\n {% for b in barcodes %}\n <tr>\n <td>{{ b.item_code }}</td>\n <td>{{ b.item_name }}</td>\n <td><img src=\"https://barcode.tec-it.com/barcode.ashx?data={{ b.barcode }}&code=Code128&dpi=96\" alt=\"{{ b.barcode }}\"></td>\n </tr>\n {% endfor %}\n </tbody>\n </table>\n</body>\n</html>\n",
"idx": 0,
"line_breaks": 0,
"margin_bottom": 15.0,
"margin_left": 15.0,
"margin_right": 15.0,
"margin_top": 15.0,
"modified": "2025-04-29 11:29:57.511867",
"modified_by": "Administrator",
"module": "Posnext",
"name": "Print Barcodes",
"owner": "Administrator",
"page_number": "Hide",
"print_format_builder": 0,
"print_format_builder_beta": 0,
"print_format_type": "Jinja",
"raw_printing": 0,
"show_section_headings": 0,
"standard": "Yes"
}
27 changes: 27 additions & 0 deletions posnext/public/js/item_list.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
frappe.listview_settings['Item'] = frappe.listview_settings['Item'] || {};

frappe.listview_settings['Item'].onload = function(listview) {
listview.page.add_actions_menu_item(__('Barcode Print'), function() {
const selected_docs = listview.get_checked_items();

if (!selected_docs.length) {
frappe.msgprint(__('Please select at least one Item'));
return;
}

const item_codes = selected_docs.map(doc => doc.name);

frappe.call({
method: 'posnext.doc_events.item.print_barcodes',
args: { item_codes },
callback: function(r) {
if (r.message && r.message.url) {
window.open(r.message.url, '_blank');
} else {
frappe.msgprint(__('Could not generate barcode print URL.'));
}
}
});
});
};

Loading