Total not calculating

I have created a new Doctype for the module Education. When I’m trying to add the table Fee component it is not giving the total.

Attached image for your reference;

U can write the client script on your custom doctype so please write the custom client script for total

Please check this

1 Like

Check the simple syntax:

Hello again,

Data is fetching properly but it is not reading the second created item. It only fetches the record from the first one.

Like for e.g. I have created 2 fee structure and divided them on student category field. When I’m selecting any student category it is fetching same same for all the categories.

What can be the reason behind this?

Can you please suggest for this.

Please share your code so we will resolve your query

1 Like

frappe.ui.form.on(‘Ksa Fees’, {
student_category: function(frm) {
// frappe.db.get_value(“Sales Invoice”, {‘name’: frm.doc.sales_invoice_id}, [‘customer’, ‘posting_date’, ‘company’], function(value) {
// frm.set_value(‘customer’, value.customer);
// frm.set_value(‘invoice_date’, value.posting_date);
// frm.set_value(‘company’, value.company);
// });

    if (frm.doc.student_category) {
        frappe.call({
            method: 'frappe.client.get',
            args: {
                doctype: "Fee Structure",
                filters: {
                    name: frm.doc.fee_structure_id
                }
            },
            callback: function(r) {
                if (r.message) {
                    console.log("------------", r.message);
                    
                    
                    r.message.components.forEach(function(component) {
                        var child = frm.add_child('f_co');
                        child.fees_category = component.fees_category
                        child.amount = component.amount
                        child.discount = component.discount
                        child.total = component.total
                        
                    });
                    frm.refresh_field('f_co');
                        
                    
                }

                
            }
        });
    }
    }

});

I have updated the code using GPT and now the debug is getting me both the data on selection but it is not printing on the table.

Below are snapshots for reference;

frappe.ui.form.on(‘Ksa Fees’, {
student_category: function(frm) {
if (frm.doc.student_category) {
frappe.call({
method: ‘frappe.client.get_list’,
args: {
doctype: “Fee Structure”,
filters: {
student_category: frm.doc.student_category // Filter by student category
},
fields: [‘name’, ‘components’]
},
callback: function(r) {
if (r.message && r.message.length > 0) {
// Debugging: log the response to ensure we’re getting the correct data
console.log(“Response received:”, r.message);

                    var fee_structure = r.message[0]; // Assuming you only need the first record

                    if (fee_structure.components && fee_structure.components.length > 0) {
                        // Clear the child table before adding new entries
                        frm.clear_table('f_co');

                        fee_structure.components.forEach(function(component) {
                            var child = frm.add_child('f_co');
                            child.fees_category = component.fees_category;
                            child.amount = component.amount;
                            child.discount = component.discount;
                            child.total = component.total;
                        });
                        frm.refresh_field('f_co');
                    } else {
                        frappe.msgprint(__('No components found for the selected student category.'));
                    }
                } else {
                    frappe.msgprint(__('No fee structure found for the selected student category.'));
                }
            }
        });
    }
}

});

Here is the updated code.

Please check the video, maybe help you!

Yes I have done the work using your code. But the problem is it is not fetching data from our type as I mentioned above, if you can check my code please.

It seems like you’ve received the response correctly. Now, you need to debug each line to find the issue. I believe it’s not just about the code; you should learn and understand how to set the values by watching the video. Copy-pasting code sometimes doesn’t work. That’s why I didn’t provide the code in the video. Users often request the code, but without understanding the concept, they just paste it, leading to issues like this. :wink:

Definitely brother, I’m not the programmer but I learnt a lot always from your responses and fixes my issues. I have done have way to my target let me figure out more to get the rest.

Many thanks, In case if I stuck some where I will try you ping you again please.

Hello everyone,

I have created a separate doctype for Saudi Education when fetching student records from the student doctype and calculating fees. I want to generate a sales invoice directly from this page by pressing the Generate Sales Invoice “Button” using the information available in my doctype.

This is my console log to generate an Invoice.

frm.add_custom_button((‘Create Sales Invoice’), function() {
frappe.confirm((‘Are you sure you want to create a Sales Invoice?’), function() {
// Create the Sales Invoice on client-side

            let sales_invoice = frappe.model.get_new_doc('Sales Invoice');



            // Set customer from your custom doctype
            sales_invoice.customer = frm.doc.student_id;  // Assuming 'customer' is a field in Saudi Fees

            // Set other fields (you can add more based on your requirements)
            sales_invoice.posting_date = frappe.datetime.nowdate();
            sales_invoice.due_date = frappe.datetime.nowdate();

            // Add items from Saudi Fees (s_record table)

            console.log(sfc);
            frm.doc.sfc.forEach((item) => {
                let new_item = frappe.model.add_child(sales_invoice, 'items');
                // Use 'student_type' as the item code
                new_item.item_code = item.student_type;
                // Fixed quantity as 1
                new_item.qty = 1;
                // Set rate as the amount field from sfc
                new_item.rate = item.amount;
                // Set amount and total (if different) from sfc
                new_item.amount = item.amount;
                new_item.total = item.total;

            });

            // Insert and save the Sales Invoice
            frappe.model.insert_doc(sales_invoice, function() {
                frappe.msgprint(__('Sales Invoice created successfully.'));
                frappe.set_route('Form', 'Sales Invoice', sales_invoice.name);
            });
        });
    });

Here is my code
I’m having issue at this point.
console.log(sfc);
frm.doc.sfc.forEach((item) => {
let new_item = frappe.model.add_child(sales_invoice, ‘items’);
// Use ‘student_type’ as the item code
new_item.item_code = item.student_type;
// Fixed quantity as 1
new_item.qty = 1;
// Set rate as the amount field from sfc
new_item.rate = item.amount;
// Set amount and total (if different) from sfc
new_item.amount = item.amount;
new_item.total = item.total;

            });

Here is my doctype from where I want to use Student Type name as student_type as an item code.

Qty is fixed to 1

Then from table name sfc to get Amount and total.

This is what I’m trying to achieve. Purpose of this separate doctype is to simply select Date, Type Student Type & Year

Calculate fees components from amout and discount using client script.

Then using using Student table to fetch student records.

And in last will create Invoice

Data for sales invoice is getting now but error on insert. When I’m trying to fix that after that giving an error of payment_terms not found server error.

frappe.get_doc({“doctype”: ‘Sales Invoice’, “description”: sales_invoice.name}).insert().then(() => {
frappe.msgprint((‘Sales Invoice created successfully.’));
frappe.set_route(‘Form’, ‘Sales Invoice’, sales_invoice.name);
}).catch((err) => {
frappe.msgprint(('Error creating Sales Invoice: ') + err.message);
});

Invoice is creating as showing in console log but unable to save it now.

Still having same payment term = undefined error

frappe.ui.form.on(‘Saudi Fees’, {
refresh: function(frm) {
const sfc = frm.doc.sfc;

    if (sfc && sfc.length > 0) {
        // Update the 'total' field calculation
        sfc.forEach((item) => {
            const total = item.amount - ((item.discount / 100) * item.amount);
            frappe.model.set_value(item.doctype, item.name, 'total', total);
        });

        frm.save();
    }

    // Add custom button to create Sales Invoice
    frm.add_custom_button(__('Create Sales Invoice'), function() {
        frappe.confirm(__('Are you sure you want to create a Sales Invoice?'), function() {
            // Create the Sales Invoice on client-side
            let sales_invoice = frappe.model.get_new_doc('Sales Invoice');
            console.log(frm.doc)
            // Set customer from your custom doctype
            sales_invoice.customer = frm.doc.student_id;  // Assuming 'student_id' is a field in Saudi Fees
            
            // Set other fields
            sales_invoice.posting_date = frappe.datetime.nowdate();
            sales_invoice.due_date = frappe.datetime.nowdate();
            // console.log(sales_invoice)
            // Add items from Saudi Fees (sfc table)
            sfc.forEach((item) => {
                if (item.amount) {
                    let new_item = frappe.model.add_child(sales_invoice, 'items', 'items');
                    // Use a placeholder item code (should be dynamically set based on your data)
                    new_item.item_code = 1;
                    new_item.qty = 1;
                    new_item.rate = item.amount;
                    new_item.amount = item.amount;
                    new_item.total = item.total;
                    console.log(item.pay_term)
                    // if (!item.pay_term) {
                    //     item.pay_term = "";  // Set to empty or a default value
                    // }
                    sales_invoice.payment_terms = "item.pay_term";
                }
            });
            
            // if (!sales_invoice.payment_terms) {
            //     sales_invoice.payment_terms = []; // Initialize an empty list or set a default value
            // }
            console.log(sales_invoice)
            // console.log(frappe.db.get_list(sales_invoice))
            // Insert and save the Sales Invoice
            // frappe.db.insert(sales_invoice).then((doc) => {
            //     frappe.msgprint(__('Sales Invoice created successfully.'));
            //     frappe.set_route('Form', 'Sales Invoice', doc.name);
            // }).catch((err) => {
            //     frappe.msgprint(__('Error creating Sales Invoice: ') + err.message);
            // });
            // let invoice = frappe.get_doc('Sales Invoice', sales_invoice.name)
            // console.log(invoice)
            //  invoice.insert(ignore_permissions = true).then(() => {
            //     frappe.msgprint(__('Sales Invoice created successfully.'));
            //     frappe.set_route('Form', 'Sales Invoice', sales_invoice.name);
            // }).catch((err) => {
            //     frappe.msgprint(__('Error creating Sales Invoice: ') + err.message);
            // });
            frappe.db.insert({
                ...sales_invoice,
                payment_terms: sales_invoice.pay_term
            }).then((doc) => {
                frappe.msgprint(__('Sales Invoice created successfully.'));
                frappe.set_route('Form', 'Sales Invoice', doc.name);
            }).catch((err) => {
                frappe.msgprint(__('Error creating Sales Invoice: ') + err.message);
            });
        
        });
    });
}

});

Here is my complete code.

sorry to tag you @NCP. If you can explain to me please where I’m making an issue in the details I shared above?

Thank you for your understanding.

try it, if does not work then one by one adding the console log and debug it.

frappe.ui.form.on('Saudi Fees', {
    refresh: function(frm) {
        const sfc = frm.doc.sfc;

        if (sfc && sfc.length > 0) {
            sfc.forEach((item) => {
                const total = item.amount - ((item.discount / 100) * item.amount);
                frappe.model.set_value(item.doctype, item.name, 'total', total);
            });
            frm.save();
        }

        frm.add_custom_button(__('Create Sales Invoice'), function() {
            frappe.confirm(__('Are you sure you want to create a Sales Invoice?'), function() {
                let sales_invoice = frappe.model.get_new_doc('Sales Invoice');
                sales_invoice.customer = frm.doc.student_id;
                sales_invoice.posting_date = frappe.datetime.nowdate();
                sales_invoice.due_date = frappe.datetime.nowdate();

                sfc.forEach((item) => {
                    if (item.amount) {
                        let new_item = frappe.model.add_child(sales_invoice, 'items', 'items');
                        new_item.item_code = 1;
                        new_item.qty = 1;
                        new_item.rate = item.amount;
                        new_item.amount = item.amount;
                        new_item.total = item.total;
                    }
                });

                frappe.db.insert(sales_invoice).then((doc) => {
                    frappe.msgprint(__('Sales Invoice created successfully.'));
                    frappe.set_route('Form', 'Sales Invoice', doc.name);
                }).catch((err) => {
                    frappe.msgprint(__('Error creating Sales Invoice: ') + err.message);
                });
            });
        });
    }
});

Brother, this is the same code I posted. I already debugged and checked. However, I’m facing an issue on this section;

frappe.db.insert(sales_invoice).then((doc) => {
frappe.msgprint((‘Sales Invoice created successfully.’));
frappe.set_route(‘Form’, ‘Sales Invoice’, doc.name);
}).catch((err) => {
frappe.msgprint(
('Error creating Sales Invoice: ') + err.message);
});

Please check the example:

1 Like