How open new doc with all data in object

Hello,
I am trying open new purchase invoice form with data stored in object in client script.
This object (new_form_object) is returned by internal erpnext function:

   frappe.call({
        method: 'frappe.model.mapper.map_docs',
        args: {
            method: 'erpnext.buying.doctype.purchase_order.purchase_order.make_purchase_invoice',
            source_names: '["PO-24-00200"]', target_doc:''
    
        },
       callback: (r) => {
            let new_form_object = r.message
		})

  }})

I know about frappe.new_doc, but something like this is not working for child tables (items in this cause):

frappe.new_doc("Purchase Invoice", doc = new_form_object);

Or should I “parse” all tables to format like this? Uf :slight_smile:

let row = frappe.model.add_child(doc, "items");
    row.item_code = new_form_object.items[0].item_code;
    row.item_name = new_form_object.items[0].item_name;
etc...

Thanks for any advice in advance.

Jiri Sir

Hi @Jiri_Sir,

Here I created a sample example of a Purchase Order to Purchase Receipt creation so check it.

Client script:

frappe.ui.form.on('Purchase Order', {
    refresh: function(frm) {
        frm.add_custom_button("Create PR", () => {
            frappe.new_doc("Purchase Receipt", {}, doc => {
                doc.supplier = frm.doc.supplier;
                // Set other fields as needed
                frappe.model.clear_table(doc, "items");

                frm.doc.items.forEach(po_item => {
                    let pr_item = frappe.model.add_child(doc, "items");
                    pr_item.item_code = po_item.item_code;
                    pr_item.qty = po_item.qty;
                    pr_item.rate = po_item.rate;
                    // Set other fields as needed
                });
            });
        });
    }
});

Output:

Hello @NCP,
thank you very much for the quick answer.

So as I see, there is no other way how prepare now form directly from prepared object. Just go through it and setup all necessary values.

For items I will try something like this:

frm.doc.items.forEach(po_item => {
           let pr_item = frappe.model.add_child(doc, "items");
               for (var key in pr_item)
			   {
					pr_item[key] = po_item[key];
			    }
             });
});

Maybe I will try for cycle for all non table values in prepared object.

Thank you any way.
Jiri Sir

Hello,
finally I am using this:

	frappe.call({
        method: 'frappe.model.mapper.map_docs',
        args: {
            method: 'erpnext.buying.doctype.purchase_order.purchase_order.make_purchase_invoice',
            source_names: po_arr,
            target_doc: ''
    },
        // freeze the screen until the request is completed
        freeze: true,
        callback: (r) => {
            frappe.new_doc("Purchase Invoice", {}, doc => {
            
                let  pi = r.message;
                
                //Standard fields w/o child tables
                for (var key in pi)
        	    {
        	        if (!Array.isArray(pi[key]))
        			    doc[key] = pi[key];
        	    }
        	    
        	    //Item child table
        	    frappe.model.clear_table(doc, "items");
        	    
        	    pi.items.forEach(po_item => {
        		    let pi_item = frappe.model.add_child(doc, "items");
                    for (var item_key in po_item)
        			{
        			    pi_item[item_key] = po_item[item_key];
        			}
                });
                
                
                //Custom fields in target doc
                doc.bee_amount = frm.doc.bee_amount;
                doc.purchase_invoice_approval = frm.doc.name;
                doc.posting_date = frm.doc.bill_date;
                doc.custom_bee_variable_symbol = frm.doc.bee_variable_symbol;
            
            });
        }
    });

I have given the reference of the video here, maybe it will help someone.

Upvoting as this is the correct way to do it imo and also works in v15 onwards. Thanks for creating this video tutorial!