On self-hosted ERPNext, I am trying to generate after item creation, a random number of 11 digits as the barcode number for the newly created item, but it is not working. I created a server script with Item as doctype, doctype event as script type, and after save as doctype event. here is the script that is not working:
def generate_random_barcode():
return frappe.utils.random_string(length=11, only_digits=True)
def after_insert(doc, method):
barcode = generate_random_barcode()
frappe.db.insert({
"doctype": "Item Barcode",
"parent": doc.name, # Reference the item name as the parent
"parenttype": "Item",
"parentfield": "barcodes",
"barcode": barcode
})
I am using naming series for the items but the item name is the same as item_code in this case. (both didn’t work)
In theory this script should work, but it isn’t working, even though I have server side scripting enabled for the site I am implementing this on
In hook file add this
doc_events = {
"Item": {
"after_insert": "path_to_file.add_barcode",
},
}
create new function called add_barcode in the file
import random
def generate_random_barcode():
return ''.join(random.choices('0123456789', k=11))
def add_barcode(doc, method):
barcode = generate_random_barcode()
doc.append('barcodes', {
"barcode": barcode
})
this will work
hello @OmarJaber , thank you for your reply.
Here is what I tried and didn’t work:
1- I edited the hooks.py file in apps/erpnext/erpnext directory to include the first code. Then I created in this directory the file item_custom_hook.py and added the second part of the code to it and saved it. Then in the hooks.py, I tried adding the path to file as erpnext.erpnext.item_custom_hook.add_barcode and as home.[my-user].frappe-bench.apps.erpnext.erpnext.item_custom_hook.add_barcode. Both didn’t work.
2- I then tried creating a custom app called custom_barcode and I installed it on the site I want to implement this functionality in. I went to the directory apps/custom_barcode/custom_barcode, and redid all the necessary actions to have in hooks.py the path to file as i did in the first approach (with path having custom_barcode.custom_barcode.item_custom_hook.add_barcode), and it still did not work, even though I created the files and added the code in both hooks.py and item_custom_hook.py.
Could you please advise on where am I doing something wrong?
Thank you in advance
Edit: after checking logs of node-socketio.log, it seems the function is erroring because the function is trying to access the item name as it is before it is inserted in the table. I am using naming series as the method of naming for the new item. so for example a new item that has the name of 00084-test in the database, is being accessed by the function as new-item-lhzzxkmtsv, so I am getting the error:
_body: {
exc_type: ‘DoesNotExistError’,
_server_messages: ‘[“{\“message\”: \“Item new-item-lhzzxkmtsv not found\”, \“title\”: \“Message\”, \“indicator\”: \“red\”, \“raise_exception\”: 1, \”__frappe_exc_id\“: \“7cb982d030f720b62ba1a7303d58a2492b4096e34ca6e7e2c44c1ce8\”}”]’
},
Never mind all that hahahaha, thank you so much, I was able to make it work.
Here is what I did after to make it work:
I went to directory apps/custom_barcode/custom_barcode/custom_barcode and added the item_custom_hook.py, then edited the file hooks.py in the directory apps/custom_barcode/custom_barcode to reference custom_barcode.custom_barcode.item_custom_hook.add_barcode, and it worked
@OmarJaber One more thing. When I create a item and define attribute has variants to be true, creating single variant for the item makes it also create the barcode for this variant, but creating multiple variants does not add the barcode to these multiple variants. Could you please help me with solving that?
never mind that also, I was able to figure it out. the Final code for this functionality is:
import random
import frappe
def generate_random_barcode():
return ''.join(random.choices('0123456789', k=11))
def is_barcode_unique(barcode):
return not frappe.db.exists("Item Barcode", {"barcode": barcode})
def generate_unique_barcode():
while True:
barcode = generate_random_barcode()
if is_barcode_unique(barcode):
return barcode
def add_barcode(doc, method):
if not doc.barcodes:
barcode = generate_unique_barcode()
doc.append('barcodes', {
"barcode": barcode
})
doc.save(ignore_permissions=True)
I added a failsafe for uniqueness of barcode in case the random chance gave the same barcode
1 Like