Add Label Printer options in print_layout html file

Hi All,

I created custom doctype called Label Printer and i made two Label Printers: 1.Citizen and 2. Zebra.
In print_layout.html, how can we add Label Printer doc options(1.Citizen and 2. Zebra) and is possible to get items details of any doc(Purchase Invoice/Purchase Receipt) when selection of Citizen/Zebra printer?
Right now I added manually in print_layout.html file. Please find in attached one.
Any suggestions?

Thanks
Ragh

it is quite difficult i think but i suggest you to add select field and custom button on your Purchase invoice and purchase reciept and then on the basis of selection field you add render your custom template in pdf format

Thanks @AkshayJadhao

@ragh The print node Integration I’m maintainer can do what you want

Sorry for the late response @max_morais_dmm
Right now we are implementing through custom script for selecting Printer options and making .PRN file for Purchase Invoice Items.

Thanks
Ragh

@ragh Could you share your custom script, I am trying to solve this issue for ages :sweat_smile:

Hii @Mohammed_Redha
The implementation almost done. I will share you after completion.

Thanks
Ragh

Hii @Mohammed_Redha
The custom script source code is :

frappe.ui.form.on(“Purchase Invoice”, “refresh”, function(frm, cdt, cdn) {
frm.add_custom_button(__(“Make Label”), function() {
var label_flag = false;
var d = new frappe.ui.Dialog({
title: __(“Select The Printer!”),
‘fields’: [{
“fieldname”: “label_printer”,
“fieldtype”: “Link”,
“options”: “Label Printer”,
“reqd”: 1,
“onchange”: function(e) {
console.log(" label_flag-----" + label_flag);
if (label_flag == false) {
if (this.value != “Citizen” && this.value != “”) {
label_flag = true;
frappe.throw(“Sorry!! This printer not available!”);
}
} else {
label_flag = false;
}
}
}],
primary_action: function() {
d.hide();
var label = d.get_values();
console.log(" label_printer-----" + label.label_printer);
display_dialog_box_for_ncopies(label.label_printer,cur_frm.doc.name);
}
});
d.show();
}); //end of custom_button…
});

function display_dialog_box_for_ncopies(label,invoice){
var d = new frappe.ui.Dialog({
title: __(“Please Submit how many copies you want!”),
‘fields’: [
{
“fieldname”: “ncopies”,
“fieldtype”: “Data”,
“label”: “Enter Copies”,
“reqd”: 1,
“onchange”: function(e) {
console.log(" ncopies-----" + this.value);
var ncopies = Number(this.value);
if (ncopies % 1 != 0) {
frappe.throw(" The Entered Copies value should be integer!");
} else if (ncopies < 0) {
frappe.throw(" The Entered Copies value should be positive!");
} else if (ncopies == 0) {
frappe.throw(" The Entered Copies value should be greater than zero!");
}
}
}
],
primary_action: function(){
d.hide();
var label_input = d.get_values();
console.log(" ncopies-----"+label_input.ncopies);
console.log(" label-----"+label);
console.log(" invoice-----"+invoice);
make_prn_file(label_input.ncopies,invoice,label);
}
});
d.show();
}

function make_prn_file(ncopies,invoice,label){//to make prn file in server side…
frappe.call({
method: “nhance.api.make_prnfile”,
args: {
“invoice”: invoice,
“ncopies”: ncopies,
“label”: label
},
async: false,
callback: function® {}
});
}

2 Likes

@ragh thanks a lot for sharing.
Could you share your code for nhance.api.make_prnfile method?

Hii @Mohammed_Redha
please find here nhance.api.make_prnfile method implementation:

@frappe.whitelist()
def make_prnfile(invoice,ncopies,label):
print “-------invoice-------------”, invoice
invoice_data = frappe.get_doc(“Purchase Invoice”, invoice)
printer_details = frappe.get_doc(“Label Printer”, label)
address = printer_details.address
split_address = address.split("\n")
items_list = invoice_data.items
path = os.path.expanduser(’~’) +’/ERPNext_PINV_PRN.PRN’
print “path--------”, path
prn_file = open(path,‘wb+’)
posting_date = invoice_data.posting_date
date_of_import = posting_date.strftime("%m/%y")

for items in items_list:
	copies = 1
	qty = items.qty
	total_copies = int(qty) * int(ncopies)
	item_record = frappe.get_doc("Item", items.item_code)
	price_list = frappe.get_doc("Item Price", {"item_code": items.item_code, "price_list": "Standard Selling"}, "price_list_rate")

	for copies in xrange(total_copies):
		prn_file.write("<xpml><page quantity='0' pitch='50.8 mm'></xpml>eG0\015" +"\n")
		prn_file.write("n\015"+"\n") 
		prn_file.write("M0500\015"+"\n") 
		prn_file.write("eMT\015"+"\n") 
		prn_file.write("O0214\015"+"\n") 
		prn_file.write("V0\015"+"\n") 
		prn_file.write("et1\015"+"\n") 
		prn_file.write("Kf0070\015"+"\n") 
		prn_file.write("SG\015"+"\n") 
		prn_file.write("c0000\015"+"\n") 
		prn_file.write("e\015"+"\n") 
		prn_file.write("<xpml></page></xpml><xpml><page quantity='1' pitch='50.8 mm'></xpml>L\015"+"\n") 
		prn_file.write("D11\015"+"\n"+"H14\015"+"\n"+"PG\015"+"\n"+"PG\015"+"\n"+"SG\015"+"\n"+"ySPM\015"+"\n"+"A2\015"+"\n") 
		prn_file.write("1911C1001760021" + str(items.item_name)+"\015"+"\n") #product-name
		prn_file.write("4911C0801000013" + str(items.item_code)+"\015"+"\n") #Barcode
		prn_file.write("1e8404201270018C0201&E0$2" + str(items.item_code)+"\015"+"\n") #ProductCode
		#prn_file.write("1911C1001570260" + "Black"+"\n") #item-color
		#prn_file.write("1911C1001570260" + "L" +"\n") #item-size
		prn_file.write("1911C1001050019Month & Yr of Import" +"\015"+ "\n") 
		prn_file.write("1911C10010501600" + str(date_of_import) + "\015"+ "\n") 
		prn_file.write("1911C1200800019M.R.P." +"\015"+ "\n") 
		prn_file.write("1911C1200800105" + str(price_list.price_list_rate) +"\015"+"\n") #selling price
		prn_file.write("1911A0800670148Inclusive of all taxes" +"\015"+ "\n") 
		prn_file.write("1911A0800990227Qty" +"\015"+ "\n") 
		prn_file.write("1911A0800830227" + str(items.qty) + " " +str(items.stock_uom) +"\015"+ "\n") # Qty and UOM
		if len(split_address)!=0:
			if len(split_address) == 3:
				prn_file.write("1911C0800400012" + str(split_address[0]) +"\015"+ "\n") 
				prn_file.write("1911C08002500206,"+ str(split_address[1]) +"\015"+ "\n") 
				prn_file.write("1911C0800090005"+str(split_address[2]) +"\015"+ "\n") 
			else:
				prn_file.write("1911C0800400012" + str(split_address[0]) +"\015"+ "\n")
		prn_file.write("Q0001\015"+"\n") 
		prn_file.write("E\015"+"\n") 
		prn_file.write("<xpml></page></xpml><xpml><end/></xpml>\015"+"\n") 
prn_file.close()
frappe.msgprint(_("ERPNext PRN file Generated in - " +path))
1 Like

@ragh how to create the file prn_file or how to design my own?
how to send prn_file to the printer?

Please pare with me :sweat_smile:

@Mohammed_Redha
Sorry! We haven’t tried with the custom prn file format.
Customer/Client will take care of, To send prn_file to the printer.

@ragh thanks, I figure out how to print it.
It should be copied to network printer then will get print .

My Last question is how to create and design prn file like what you did like :

:prn_file.write("c0000\015"+"\n")

@ragh Any Help?

sorry for the late response @Mohammed_Redha
Actually the design things we got from client.

Dear All,
I have set up a reasonably simple label printing facility using self-hosted JsBarcode, as in:

su - ${INSTANCE}
JSBARCODE_VERSION=[3.11.0]
cd ~/frappe-bench/sites/assets/js
wget https://cdn.jsdelivr.net/npm/jsbarcode@${JSBARCODE_VERSION}/dist/JsBarcode.all.min.js

I have created customised print templates for barcode labels, with serial numbers and the works.
I can print those labels one by one, but not several ones in one go, because wkhtmltopdf does not recognise the JsBarcode output. Any clues?
Also, anyone, who want to get more details on how to set up label creation and printing (and bypassing the A4/Letter paper size limitation hardcoded into ERPNext), please let me know, and I open a separate thread with more details.
Cheers!
Chris

@ragh @Mohammed_Redha the recently added ‘Raw Printing’ Feature might interest you! you can now directly send these commands to a printer instead of saving it to a PRN file. Please use this feature and share your feedback.

@clarsen “JsBarcode.all.min.js” library is included in the Frappe Framework. you can access it via the global object ‘JsBarcode’ in javascript. You do not need to import it again. Also, ‘JsBarcode’ would not be available to the ‘wkhtmltopdf’ as it is a JS library. I think your requirement might be solved using ‘Raw Printing’ Feature, depending on what printer you are using.

Thanks a lot, indeed, for the heads-up regarding the existing inclusion of JsBarcode. This greatly simplified my code.
As for the raw printing feature, I am a bit lost. I am using a Bixolon label printer (which uses essentially Zebra drivers). Any hints? Thanks a lot!
Chris