Hi Everyone,
I have written a code to clone an item code. This code will run when user opens an existing item code and clicks on “clone this item” then the code will duplicate the current item.
Below is my code of Client-Side Custom Script.
frappe.ui.form.on("Item", "clone_this_item", function(frm, doctype, name) {
frappe.model.open_mapped_doc({
method: "library.item_script.generate_document_clone",
frm: cur_frm
});
window.location.reload(true);
});
Here is my code of Server-Side Script.
@frappe.whitelist(allow_guest=True)
def generate_document_clone(source_name, target=None):
doc_m = frappe.get_doc("Item", source_name)
i=doc_m.item_group[:3]+'%'
j=frappe.db.sql("""select item_code from tabItem where item_code like %s order by item_code desc limit 1""",i)
prefix=j[0][0]
prefix="".join(prefix)
new_prefix=prefix[0:3]
new_suffix=prefix[4:10]
next_num=(int(new_suffix)+1)
next_num1=str(next_num)
new_num1=next_num1.decode("ascii").rjust(6,'0')
new_num1=new_prefix+'-'+new_num1
new_item=frappe.new_doc("Item")
new_item.item_code =new_num1
new_item.item_group = doc_m.item_group
new_item.item_name = "This is the clone of "+doc_m.item_name
new_item.brand = doc_m.brand
new_item.description = doc_m.description
#new_item.barcode = doc_m.barcode
new_item.re_order_level = doc_m.re_order_level
new_item.re_order_qty = doc_m.re_order_qty
#new_item.apply_warehouse_wise_reorder_level = doc_m.apply_warehouse_wise_reorder_level
#new_item.has_variants = doc_m.has_variants
frappe.msgprint("New Item Code "+new_num1+" has been generated");
new_item.is_purchase_item=doc_m.is_purchase_item
new_item.min_order_qty=doc_m.min_order_qty
new_item.lead_time_days=doc_m.lead_time_days
new_item.buying_cost_center=doc_m.buying_cost_center
new_item.expense_account=doc_m.expense_account
#new_item.uoms=doc_m.uoms -- Conversion Factor
new_item.default_supplier=doc_m.default_supplier
new_item.last_purchsae_rate=doc_m.last_purchase_rate
new_item.manufacturer=doc_m.manufacturer
new_item.manufacturer_part_no=doc_m.manufacturer_part_no
#new_item.supplier_items=doc_m.supplier_items
new_item.is_sales_item=doc_m.is_sales_item
new_item.is_service_item=doc_m.is_service_item
new_item.publish_in_hub=doc_m.publish_in_hub
new_item.synced_with_hub=doc_m.synced_with_hub
new_item.income_account=doc_m.income_account
new_item.selling_cost_center=doc_m.selling_cost_center
#new_item.customer_items=doc_m.customer_items
new_item.max_discount=doc_m.max_discount
#new_item.taxes=doc_m.taxes
new_item.inspection_required=doc_m.inspection_required
#new_item.quality_parameters=doc_m.quality_parameters
new_item.is_pro_applicable=doc_m.is_pro_applicable
new_item.is_sub_contracted_item=doc_m.is_sub_contracted_item
new_item.customer_code=doc_m.customer_code
new_item.show_in_website=doc_m.show_in_website
new_item.page_name=doc_m.page_name
new_item.weightage=doc_m.weightage
new_item.slideshow=doc_m.slideshow
new_item.website_image=doc_m.website_image
new_item.website_warehouse=doc_m.website_warehouse
#new_item.website_item_groups=doc_m.website_item_groups
#new_item.copy_from_item_group=doc_m.copy_from_item_group
#new_item.website_specifications=doc_m.website_specifications
new_item.web_long_description=doc_m.web_long_description
new_item.parent_website_route=doc_m.parent_website_route
if not doc_m.default_warehouse is None:
new_item.default_warehouse = doc_m.default_warehouse
new_item.end_of_life =doc_m.end_of_life
new_item.stock_uom =doc_m.stock_uom
new_item.tolerance = doc_m.tolerance
new_item.has_batch_no = doc_m.has_batch_no
new_item.has_serial_no = doc_m.has_serial_no
#new_item.serial_no_series = doc_m.serial_no_series
new_item.valuation_method = doc_m.valuation_method
new_item.warranty_period = doc_m.warranty_period
new_item.net_weight = doc_m.net_weight
new_item.weight_uom = doc_m.weight_uom
new_item.is_asset_item = doc_m.is_asset_item
new_item.default_bom=doc_m.default_bom
new_item.insert();
doc_m.set("cloned_item_code",new_num1);
doc_m.save();
doc_m.run_method("on_update");
Earlier the code was running fine, but now when we tried to duplicate an item using the button it started raising errors.
Below is the error:
Traceback (innermost last):
File “/home/erpnext/frappe-bench/apps/frappe/frappe/app.py”, line 69, in application
response = frappe.handler.handle()
File “/home/erpnext/frappe-bench/apps/frappe/frappe/handler.py”, line 77, in handle
execute_cmd(cmd)
File “/home/erpnext/frappe-bench/apps/frappe/frappe/handler.py”, line 94, in execute_cmd
ret = frappe.call(method, **frappe.form_dict)
File “/home/erpnext/frappe-bench/apps/frappe/frappe/init.py”, line 788, in call
return fn(*args, **newargs)
File “/home/erpnext/frappe-bench/apps/library/library/item_script.py”, line 93, in generate_document_clone
new_item.insert();
File “/home/erpnext/frappe-bench/apps/frappe/frappe/model/document.py”, line 192, in insert
self.run_before_save_methods()
File “/home/erpnext/frappe-bench/apps/frappe/frappe/model/document.py”, line 589, in run_before_save_methods
self.run_method(“validate”)
File “/home/erpnext/frappe-bench/apps/frappe/frappe/model/document.py”, line 551, in run_method
return Document.hook(fn)(self, *args, **kwargs)
File “/home/erpnext/frappe-bench/apps/frappe/frappe/model/document.py”, line 706, in composer
return composed(self, method, *args, **kwargs)
File “/home/erpnext/frappe-bench/apps/frappe/frappe/model/document.py”, line 689, in runner
add_to_return_value(self, fn(self, *args, **kwargs))
File “/home/erpnext/frappe-bench/apps/frappe/frappe/model/document.py”, line 545, in
fn = lambda self, *args, **kwargs: getattr(self, method)(*args, **kwargs)
File “/home/erpnext/frappe-bench/apps/erpnext/erpnext/stock/doctype/item/item.py”, line 51, in validate
self.check_warehouse_is_set_for_stock_item()
File “/home/erpnext/frappe-bench/apps/erpnext/erpnext/stock/doctype/item/item.py”, line 299, in check_warehouse_is_set_for_stock_item
raise_exception=WarehouseNotSet)
File “/home/erpnext/frappe-bench/apps/frappe/frappe/init.py”, line 250, in msgprint
_raise_exception()
File “/home/erpnext/frappe-bench/apps/frappe/frappe/init.py”, line 235, in _raise_exception
raise raise_exception, encode(msg)
WarehouseNotSet: Default Warehouse is mandatory for stock Item.
Above error clearly says that “Default Warehouse is mandatory for stock Item.”
but the item from which I am duplicating the code is not a stock item.
Also, I have played with the condition as well
if not doc_m.default_warehouse is None:
new_item.default_warehouse = doc_m.default_warehouse
I appreciate if anyone can help me in this regard.
item.py-----Code of item.py -----------
def check_warehouse_is_set_for_stock_item(self):
if self.is_stock_item==1 and not self.default_warehouse and frappe.get_all("Warehouse"):
frappe.msgprint(_("Default Warehouse is mandatory for stock Item."),
raise_exception=WarehouseNotSet)
Item Screenshot:
Regards
Ruchin Sharma