ERPNext.com Frappe Cloud Support Partners Foundation Frappe School

Creating Sales Invoices with prefilled data from different doctypes

Hello Fellas

I have to prepare the sales invoice with different Doctypes which will have custom fields only.
I would like to Implement the funcationality as per below

  1. Doctype A (with unique custom fileds related to DocType A) ---- Creates the sales invoice with prefilled data (with imported unique fields from Doctype A)
  2. Doctype B (with unique custom fileds related to DocType B) ---- Creates the sales invoice with prefilled data (with imported unique fields from Doctype B)

and so on.

Is this possible? If Yes, how?

use mapped doc function or set_route with route arguments

Hi Neeraj,

Unfortunately, not aware of these, tries searching for mapped doc function but not able to understand where to start.

Route Example:

frappe.route_options = {
    "customer": frm.doc.customer,
    "status": "Open",
    "reference_doctype": "Patient Medical Record",
    "reference_owner": frm.doc.owner
};
frappe.new_doc("Sales Invoice");

You can add a button in DocA like:

    frm.add_custom_button(__("Create Invoice"), function() {
         frappe.route_options...
    });

Frapper route options to be used in PY file as server script?
Ot it needs to be entered as a client script?

it is client script

We have done the same for one of our clients.
We have created custom doc Inquiry and then based on the details filled in the Inquiry, Sales order is being created.

below is the custom script for both

In Inquiry

frappe.ui.form.on("Inquiry", {
"refresh": function(frm, cdt, cdn) {
    var d = locals[cdt][cdn];
        frm.add_custom_button(__("Create Sales Order"), function() {
            frappe.new_doc('Sales Order', {
                "customer": cur_frm.doc.company_name,
                "inquiry_no": cur_frm.doc.name
            });
        });
    }
});

And in Sales Order

frappe.ui.form.on("Sales Order", {
    "refresh": function(frm, cdt, cdn) {
        if(frm.doc.__islocal && frm.doc.inquiry_no){
            frappe.model.with_doc("Inquiry", frm.doc.inquiry_no, function() {
                var mcd = frappe.model.get_doc("Inquiry", frm.doc.inquiry_no);
                cur_frm.clear_table("items");
                    $.each(mcd.items, function(i, d) {
                        i = frm.add_child("items");
                        i.item_code = d.item_code;
                        i.item_name = d.item_name;
                        i.product_make = d.product_make;
                        i.cas_no = d.cas_no;
                        i.uom = d.uom;
                        i.stock_uom = d.uom;
                        i.description = d.description;
                        i.qty = d.qty;
                    });
                cur_frm.refresh_field("items");
            });
        }
    }
});

Hope it helps!!

1 Like

Hi @mohitchechani

Thanks for replying. On my custom DocType (AirImports Booking), I applied below client script.

frappe.ui.form.on("AirImports Booking", {
refresh: function(frm, cdt, cdn) {
    var d = locals[cdt][cdn];
        frm.add_custom_button(__("Create Sales Invoice"), function() {
            frappe.new_doc('Sales Invoice', {
                "customer": cur_frm.doc.customer,
                "Ref_no": cur_frm.doc.name,
                "shipper_name": cur_frm.doc.shipper_name,
                "consignee_name": cur_frm.doc.consignee_name,
                "MAWB#": cur_frm.doc.mawb,
                "MAWB_Dt": cur_frm.doc.mawb_dt,
                "HAWB#": cur_frm.doc.hawb,
                "HAWB_Dt": cur_frm.doc.hawb_dt,
                "Origin_Airport": cur_frm.doc.origin_airport,
                "Destination_Airport": cur_frm.doc.Destination_Airport,
                "Incoterms": cur_frm.doc.incoterms,
                "No._of_Packages": cur_frm.doc.no_of_packages,
                "Gross_Weight_(Kgs)": cur_frm.doc.gross_weight,
                "Chargeable_Weight_(Kgs)": cur_frm.doc.chargeable_weight,
                "CBM": cur_frm.doc.cbm,
                "Commodity": cur_frm.doc.commodity,
                "BOE_No.": cur_frm.doc.boe_no,
                "BOE_Dt.": cur_frm.doc.bill_of_entry_dt
            });
        });
    }
}
);

Now, On the scripting for the “Sales Invoice”, I am confused how to create the script for the sales invoice to contain all above mentioned custom fields with prefilled data fetched from the “AirImports Booking”.

AirImports Booking is just one of 6 doctype i have created. So, for each custom doctype, we need to use sales invoice with the custom fileds used in these custom doctype.

Can you guide?

Hello!!

I think you have put the Field Label on left side.
On the left side, all the fieldname of the Sales Invoice should be there and on the left side its corresponding field from your corresponding Doc type.

You need to create this script only in Custom Doctype.

If any child table is to be fetched from Custom Doctype to Sales Invoice.

Then below script should be used in client script of Sales Invoice

frappe.ui.form.on("Sales Order", {
"refresh": function(frm, cdt, cdn) {
    if(frm.doc.__islocal && frm.doc.inquiry_no){
        frappe.model.with_doc("Inquiry", frm.doc.inquiry_no, function() {
            var mcd = frappe.model.get_doc("Inquiry", frm.doc.inquiry_no);
            cur_frm.clear_table("items");
                $.each(mcd.items, function(i, d) {
                    i = frm.add_child("items");
                    i.item_code = d.item_code;
                    i.item_name = d.item_name;
                    i.product_make = d.product_make;
                    i.cas_no = d.cas_no;
                    i.uom = d.uom;
                    i.stock_uom = d.uom;
                    i.description = d.description;
                    i.qty = d.qty;
                });
            cur_frm.refresh_field("items");
        });
    }
}

});

And yes, you need to create script for each doctype

1 Like

Okay, So i changed this.
Now, the custom field containing int and float are not being copied.
All the data field have been copied successfully.

What could be the reason behind it?

Pls check the field type on both the document

Its date in both docs.

Source Doc:

Sales Invoice:

Apart from Dates, Field type INT and FLOAT are not being copied as well.

pls share the code

frappe.ui.form.on("AirImports Booking", {
    refresh: function(frm, cdt, cdn) {
        // var d = locals[cdt][cdn];
            frm.add_custom_button(__("Create Sales Invoice"), function() {
                frappe.new_doc('Sales Invoice', {
                    "customer": cur_frm.doc.customer,
                    "naming_series": cur_frm.doc.ref_no,
                    "shipper_name": cur_frm.doc.shipper_name,
                    "consignee_name": cur_frm.doc.consignee_name,
                    "mawb": cur_frm.doc.mawb,
                    "mawb_dt": cur_frm.doc.mawb_date,
                    "hawb": cur_frm.doc.hawb,
                    "hawb_dt": cur_frm.doc.hawb_date,
                    "origin_airport": cur_frm.doc.origin_airport,
                    "destination_airport": cur_frm.doc.destination_airport,
                    "incoterms": cur_frm.doc.incoterms,
                    "no_of_packages": cur_frm.doc.no_of_packages,
                    "gross_weight": cur_frm.doc.gross_weight_in_kgs,
                    "charegeable_weight": cur_frm.doc.chargeable_weight_in_kgs,
                    "cbm": cur_frm.doc.cbm,
                    "commodity": cur_frm.doc.commodity,
                    "boe_no": cur_frm.doc.boe_no,
                    "bill_of_entry_dt": cur_frm.doc.boe_date
                });
            });
        }
    }
);

it should be “hawb_date”: cur_frm.doc.hawb_dt,
&
“mawb_date”: cur_frm.doc.mawb_dt,

But if in the sales doctype date field if the default value is Today, the date value may not work

I matched both the fields with same name, but still its not copying the result from the source doctype.
Same also goes with “INT” & “FLOAT” type fileds as well.

Dear @rmehta ji, can you help on this topic?

Tried this frappe.route , but it’s failing to copy field type INT, DATE, FLOAT.