Frappe.call in before_cancel

Hi Everyone,
I am calling a server side function from Supplier Quotation on before_cancel trigger.

My Python Code:

@frappe.whitelist(allow_guest=True)
def check_if_doc_is_linked1(source_name, method="Cancel"):
	doc_m = frappe.get_doc("Supplier Quotation", source_name)
	frappe.msgprint("Function Called")
	"""
		Raises excption if the given doc(dt, dn) is linked in another record.
	"""
	from frappe.model.rename_doc import get_link_fields
	link_fields = get_link_fields(doc_m.doctype)
	link_fields = [[lf['parent'], lf['fieldname'], lf['issingle']] for lf in link_fields]
	for link_dt, link_field, issingle in link_fields:
		if not issingle:
			for item in frappe.db.get_values(link_dt, {link_field:doc_m.name},
				["name", "parent", "parenttype", "docstatus"], as_dict=True):
				if item and ((item.parent or item.name) != doc_m.name) \
						and ((method=="Delete" and item.docstatus<2) or (method=="Cancel" and item.docstatus==0)):
					# raise exception only if
					# linked to an non-cancelled doc when deleting
					# or linked to a submitted doc when cancelling
					frappe.throw(_('Cannot delete or cancel because {0} <a href="#Form/{0}/{1}">{1}</a> is linked with {2} <a href="#Form/{2}/{3}">{3}</a>')
						.format(doc_m.doctype, doc_m.name, item.parenttype if item.parent else link_dt,
						item.parent or item.name), frappe.LinkExistsError)

My JS Code:

frappe.ui.form.on("Supplier Quotation","before_cancel", function(frm, doctype, name) { 
msgprint("Called");
var data1 =  {
	    //"doc": frm.name
	     frm: cur_frm
           };
	    frappe.call({
                       method: "library_management.delete_doctype.check_if_doc_is_linked1",
	               args: data1,
                       callback: function(r) 
                      { }
});
msgprint("Code Passed");
});

Does anybody have any idea where is the mistake?

Regards
Ruchin Sharma

frappe.call does to complete before the on_cancel function completes (basic async!)

@rmehta
Sorry to say but I didn’t understand your answer well.
If frappe.call gets completed before the on_cancel function completes then why my frappe.call is not able to call a library function?

Regards
Ruchin Sharma

With some changes my function is working now:

JS Code:

frappe.ui.form.on("Supplier Quotation","before_cancel", function(frm, doctype, name) { 
msgprint("Before Cancellation");
var data1 =  {
	    //"doc": frm.name
	     source_name: frm.doc.name
             };
	    frappe.call({
                       method: "library_management.dell_doctype.check_links",
	              args: data1,
                       callback: function(r) 
                      { }
});
msgprint("After Cancellation");
});

PY Code:

@frappe.whitelist(allow_guest=True)
def check_links(source_name, method="Cancel"):
	x = frappe.db.sql("""select m.name from `tabPurchase Order` m,`tabPurchase Order Item` d where d.parent=m.name and d.supplier_quotation=%s and m.docstatus=0""",source_name)
	if x:
		frappe.throw(_('Cannot delete or cancel because this supplier quotation is linked with {0}').format(x), frappe.LinkExistsError)

Now, the only problem I am facing is, it is giving error message mentioned in the Python Script, using

frappe.throw

But it is not stopping the Supplier Quotation to cancel, whereas after giving the error message the supplier quotation gets cancelled.

Regards
Ruchin Sharma