Set_Query on Refresh Trigger Doesnt work all the time

Ammended: I have a set_query on shipping_address in Purchase Order which used to work all the time. After upgrading to the latest version it works once in awhile and doesnt most of the time. Any idea why?

cur_frm.set_query("shipping_address", function() {
        return {
            "filters": {
                "docstatus": "0"
            }
        };
    });

@bohlian,

Try setting up your set_query in setup trigger instead of refresh

@makarand_b thanks but it didnt work. Buying Controller’s query seems to take precedence:

onload: function() {
		this.setup_queries();
		this._super();

		/* eslint-disable */
		// no idea where me is coming from
		if(this.frm.get_field('shipping_address')) {
			this.frm.set_query("shipping_address", function() {
				if(me.frm.doc.customer) {
					return {
						query: 'frappe.contacts.doctype.address.address.address_query',
						filters: { link_doctype: 'Customer', link_name: me.frm.doc.customer }
					};
				} else
					return erpnext.queries.company_address_query(me.frm.doc)
			});
		}
		/* eslint-enable */
	},

Just to share, I think there is absolutely no way to control and therefore determine which AJAX call gets returned reliably. Therefore, although not the best design, one way to defeat this is to have the query run every time the field is clicked on. Again, not the best in design but if you have such a requirement, this is what you can do:

frappe.ui.form.on("Purchase Order", "refresh", function(frm) {
    cur_frm.fields_dict.shipping_address_name.$input.on("click", function() {
        //Show all Shipping Addresses even those not linked to the selected Customer
        cur_frm.set_query("shipping_address_name", function() {
            return {
                "filters": {
                    "docstatus": "0"
                }
            };
        });
    });
});

Seems to work so far…

3 Likes

save my day thanks for share @bohlian

We had this script in production on some systems and it started to produce errors. Our new workaround is to use two triggers: onlod_post_render and refresh. This way we can overwrite existing queries in all possible loading scenarios: refreshing, reloading, navigating between records, visiting the URL directly.

frappe.ui.form.on("Purchase Order", {
    onload_post_render: function(frm) {
        frm.set_query("shipping_address", function() {
            return {
                "filters": { /* my filters */ }
            };
        });
    },
    refresh: function(frm) {
        frm.set_query("shipping_address", function() {
            return {
                "filters": { /* my filters */ }
            };
        });
    },
});