How do I pass an argument to python script from custom script (cur_frm.set_query)

I want to populate one of my forms dropdown by doing a sql query. I have created a custom_script with the following:

frappe.ui.form.on("Purchase Invoice", "onload_post_render", function(frm) {
    cur_frm.set_df_property("return_against","read_only",false);
        cur_frm.set_query("return_against", function() {
            return {
                query: "erpnext.stock.doctype.purchase_receipt.purchase_receipt.make_debit_note_query",
                args: {"pr_number": cur_frm.purchase_receipt}         
            };
        });
});

In the server side python script I want to do:

def make_debit_note_query(doctype, txt, searchfield, start, page_len, filters):
        return frappe.db.sql("""select parent from `tabPurchase Invoice Item`
                            where purchase_receipt = '%s'""" % args.get('pr_number'))

The problem is my make_debit_note_query cannot seem to see my args dict. Can someone help me ?

Try this

frappe.ui.form.on("Purchase Invoice", "onload_post_render", function(frm) {
    cur_frm.set_df_property("return_against","read_only",false);
        cur_frm.set_query("return_against", function() {
            return {
                query: "erpnext.stock.doctype.purchase_receipt.purchase_receipt.make_debit_note_query",
                args: {
                        filters:{"pr_number": cur_frm.purchase_receipt}
                 }         
            };
        });
});

In Server Side

def make_debit_note_query(doctype, txt, searchfield, start, page_len, filters):
        return frappe.db.sql("""select parent from `tabPurchase Invoice Item`
                            where purchase_receipt = '%s'""" % filters.get('pr_number'))
2 Likes

This does not work for me, it complains:

  File "/home/strella/frappe-bench/apps/erpnext/erpnext/stock/doctype/purchase_receipt/purchase_receipt.py", line 658, in make_debit_note_query
    frappe.msgprint(_(filters.get(pr_number)))
 AttributeError: 'NoneType' object has no attribute 'get'

https://frappe.github.io/frappe/user/en/guides/app-development/overriding-link-query-by-custom-script.html

edit: https://frappe.io/docs/user/en/guides/app-development/overriding-link-query-by-custom-script

  1. The above link suggests to pass filters directly, not through args.
  2. checkout the lead_query from example, you will also have to factor in doctype, txt, searchfield, start, page_len for consistent user experience. If these arguments are not used, narrowing down link as you type won’t work.
2 Likes

Oh Sorry,
Need to change.

frappe.ui.form.on("Purchase Invoice", "onload_post_render", function(frm) {
    cur_frm.set_df_property("return_against","read_only",false);
        cur_frm.set_query("return_against", function() {
            return {
                query: "erpnext.stock.doctype.purchase_receipt.purchase_receipt.make_debit_note_query",
                filters: {
                        "pr_number": cur_frm.purchase_receipt
                 }         
            };
        });
});
1 Like

Hello @revant_one

I have two questions please:

  1. doctype, txt, searchfield, start, page_len, filters:
    What is the txt and start paramters?
    doctype is represting the doctype of .py or which doctype?

  2. I see the usage for this syntax: ‘txt’: “%%%s%%” % txt, why to use this format “%%%s%%” % txt?

Regards
Bilal

Hello @mainul
Can you please help me in the following issue:

The returned values for the drop down, when you click on this drop down and need to select value, and if you typed first character for example “a”, it will bring the values that start by character “a”?

Regards
Bilal

Look as the previous reply that you asked.

1. Doctype is linked dictype that you mentioned in options for link field.

2. text is that you type (‘a’)

If you want to those values that start with ‘a’ then you need to format it like “%s%%”
Check The below change:

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': "%%%s%%" % txt,
            '_txt': txt.replace("%", ""),
            'start': start,
            'page_len': page_len
        })

To

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': "%s%%" % txt,
            '_txt': txt.replace("%", ""),
            'start': start,
            'page_len': page_len
        })

Hi, I am using the same thing given above and i get the correct dropdown list but not able to select it. After selecting the value vanishes from the field. Any idea why ?
Below is my code -

def get_subjects(doctype, txt, searchfield, start, page_len, filters):
student_group_doc = frappe.get_doc(‘Student Group’,filters[‘group_name’])
if student_group_doc.program_and_stream:
subject_list = frappe.db.sql(“”"
SELECT sub.subject_name
FROM
tabStudent Group as sg
JOIN
tabProgram Stream Semester Wise Syllabus as ps
ON ps.program_and_stream = sg.program_and_stream
JOIN
tabsubjects as sub
ON sub.parent = ps.name
WHERE
sg.name = %(groupname)s
AND
SUBSTRING(sg.academic_term,LENGTH(sg.academic_term),LENGTH(sg.academic_term)) = ps.semester
AND
sub.subject_name like %(txt)s
limit %(start)s, %(page_len)s
“”“.format(**{
‘key’: searchfield,
‘mcond’:get_match_cond(doctype)
}),
{
‘txt’: “%s%%” % txt,
‘_txt’: txt.replace(”%", “”),
‘start’: start,
‘page_len’: page_len,
‘groupname’ : filters[‘group_name’]
})
return subject_list