ERPNext Conference 2019* ERPNext.com Blog

Auto populate child table in purchase receipt

customization
erpnext

#1

Hello everyone,
I want to populate Item table in Purchase Receipt when supplier name is selected.

I am fetching values from tabItem Supplier in Item table.

Please help me with this.


#2

Instead of fetching it automatically, you could do this on the click of a button which you can place above the Items Table. Also, do you have access to code ?


#3

Thanks for replying @root13F,
But I want to fetch all the items when I am selecting a supplier.
I have tried something

js:
supplier: function(frm) { //fetch items
frappe.call({
method: “erpnext.stock.doctype.purchase_receipt.purchase_receipt.get_items_list”,
doctype: “Purchase Receipt”,
items: cur_frm.doc.items,
callback :function®{
var child = cur_frm.add_child(“items”);
frappe.model.set_value(child.doctype, child.name, “item_code”, r.message);
cur_frm.refresh_field(“items”)
}
});
}

python:
@frappe.whitelist()
def get_items_list(self):
items = frappe.db.sql(""“select parent from tabItem Supplier“””,as_dict=1)
return items

and getting this error,

Please help me to solve this error…


#4

Python File
@Saditi,
remove self from your python method
@frappe.whitelist()
def get_items_list():
items = frappe.db.sql(""“select parent from tabItem Supplier “””,as_dict=1)
return items

call your python method like this from JS FILE

supplier: function(frm) { //fetch items
    	frappe.call({
    		method: "erpnext.stock.doctype.purchase_receipt.purchase_receipt.get_items_list",
    		callback :function(r){
    			console.log(r.message);
    			var child = cur_frm.add_child("items");
    			frappe.model.set_value(child.doctype, child.name, "item_code", r.message);
    			cur_frm.refresh_field("items");
    		}
    	});
    }

#5

Thanks for replying @ROHAN_JAIN1,

Still getting error,

If I am trying this,

@frappe.whitelist()
def get_items_list(supplier=None):
items = frappe.db.sql(""“select parent from tabItem Supplier“””, as_dict=1)
return items[1].parent
It will fetch only one row.


#6

@Saditi
If u want only one row to be fetched then use limit in your query.
select parent from tabItem Supplier limit 1;

as you are returning dict(JSON) so how to access it like JSON Array in Javascript.


#7

@ROHAN_JAIN1,
I want to fetch all the items for a supplier .


#8

@Saditi Want to add into child table or want to show them into the dropdown option?


#9

So I was able to try this and get the desired effect, however I did this on a button click:

Python:

import frappe

@frappe.whitelist()
def get_items_supplied(supplier):
    items = frappe.get_all(
        "Item Supplier",
        {"supplier":supplier},"parent",
        as_dict=1)
    return items

Javascript

fetch_supplied_items is my button field.

frappe.ui.form.on("Purchase Receipt",{
    "fetch_supplied_items": function(frm, cdt, cdn){
        frappe.call({
            method:"randomcode.randomcode.scripts.validations.get_items_supplied",
            args:{
                supplier:frm.doc.supplier
            },
            callback:function(r){
                if (r.message){
                    //setting the table empty, erpnext now has one row by default
                    if(frm.doc.items){
                        frm.set_value("items",[])
                    }
                    $.each(r.message, function(i, item) {
                        var item_row = frm.add_child("items")
                        console.log(item)
                        item_row.item_code = item.parent
					});
                }
            }
        })
        frm.refresh()
    }
})

#10

@ROHAN_JAIN1 , Want to add into child table


#11

@root13F ,
I will try this and get back to u soon


#12

Just a thought, nice code snippet, but is a server-side code required? What if this API call was used:

frappe.call({
    method:"frappe.client.get_list",
    args:{
        doctype:"Item Attribute Value",
        filters: [
            ["supplier","=", frm.doc.supplier]
        ],
        fields: ["parent"],
        parent: "Supplier"
    },
    callback: function (response) {
        /* see above */
    }
});

#13

Thanks @root13F, it worked


#14

Wow this is great for people who rely on custom script ! I never used this. And yes, given how small that code is, it makes sense to use this JS itself.

@Saditi @lasalesi makes more sense in your case, as there is too little to be done by using Python here.