to select ↑↓ to navigate
Framework

Framework

Open in ChatGPT
Ask ChatGPT about this page
Open in Claude
Ask Claude about this page

Overriding Link Query By Custom Script

You can override the standard link query by using set_query via the Client Script DocType from the desk.

The set_query method takes one of two formats: set_query(field_name, options_function()) for regular fields, or set_query(field_name, child_table_name, options_function()) for fields in child tables.

1. Adding Filters

You can add filters to the query:

frappe.ui.form.on("Bank Reconciliation", "onload", function(frm) {
 frm.set_query("bank_account", function() {
 return {
 "filters": {
 "account_type": "Bank",
 "group_or_ledger": "Ledger"
 }
 };
 });
});

A more complex query:

frappe.ui.form.on("Bank Reconciliation", "onload", function(frm){
 frm.set_query("bank_account", function(){
 return {
 "filters": [
 ["Bank Account", "account_type", "=", "Bank"],
 ["Bank Account", "group_or_ledger", "!=", "Group"]
 ]
 }
 });
});

2. Calling a Different Method to Generate Results

You can also set a server side method to be called on the query:

frm.set_query("item_code", "items", function() {
 return {
 query: "erpnext.controllers.queries.item_query",
 filters: frm.doc.enquiry_type === "Maintenance" ?
 {"is_service_item": "Yes"} : {"is_sales_item": "Yes"}
 };
});

Custom Method

The custom method should return a list of items for auto select. If you want to send additional data, you can send multiple columns in the list.

Parameters to the custom method are:

def custom_query(doctype, txt, searchfield, start, page_len, filters)

Example:

# searches for leads which are not converted
@frappe.whitelist()
@frappe.validate_and_sanitize_search_inputs
def lead_query(doctype, txt, searchfield, start, page_len, filters):
 return frappe.db.sql("""
 SELECT name, lead_name, company_name
 FROM `tabLead`
 WHERE docstatus < 2
 AND ifnull(status, '') != 'Converted'
 AND ({key} LIKE %(txt)s
 OR lead_name LIKE %(txt)s
 OR company_name LIKE %(txt)s)
 {mcond}
 ORDER BY
 IF(LOCATE(%(_txt)s, name), LOCATE(%(_txt)s, name), 99999),
 IF(LOCATE(%(_txt)s, lead_name), LOCATE(%(_txt)s, lead_name), 99999),
 IF(LOCATE(%(_txt)s, company_name), LOCATE(%(_txt)s, company_name), 99999),
 name, lead_name
 LIMIT %(start)s, %(page_len)s
 """.format(**{
 'key': searchfield,
 'mcond':get_match_cond(doctype)
 }), {
 'txt': "%{}%".format(txt),
 '_txt': txt.replace("%", ""),
 'start': start,
 'page_len': page_len
 })

Note: @frappe.whitelist() is used to expose lead_query to the client-side and @frappe.validate_and_sanitize_search_inputs decorator is used to validate and sanitize user inputs sent through API or client-side request to avoid possible SQLi.

For more examples see:

https://github.com/frappe/erpnext/blob/develop/erpnext/controllers/queries.py

Last updated 3 months ago
Was this helpful?
Thanks!