Catalog Item – How to calculate total bill from multiple price fields

neehas710
Tera Contributor

Hi Community,

I am working on a Service Catalog Item that allows the user to select food items (Veg and Non-Veg) with corresponding prices.

I have almost completed all the configuration:

  • Field visibility is controlled by UI Policies based on selection of Veg or Non-Veg.

  • Prices are stored in readonly single-line text variables, for example Veg Manchuria Price = 300.

  • Each item is a checkbox, and when selected, its price field is displayed.

  • There is also an Available Offers field with choice values 10 percent, 20 percent, and 30 percent that should apply a discount to the total.

Where I am stuck:
I need to get all the selected item prices, sum them up, apply the offer if any, and display the final value in the Total Bill readonly field.

I am unsure how to:

  1. Retrieve the prices from all visible and checked items in a client-side script.

  2. Sum them dynamically when items are checked or unchecked.

  3. Apply the discount percentage from the Available Offers field.

Example of my setup:
Veg Manchuria (checkbox) and Veg Manchuria Price = 300
Chicken Biryani (checkbox) and Chicken Biryani Price = 400
Mutton Biryani (checkbox) and Mutton Biryani Price = 600
Total Bill should sum all selected prices and apply discount.

Question:
What is the best way to achieve this in a ServiceNow Catalog Client Script? Should I loop through variable names in an onChange script for each checkbox, or is there a more efficient way?

Thanks in advance for your guidance.

4 REPLIES 4

SAI VENKATESH
Tera Sage
Tera Sage

Hi @neehas710 

 

@you can write catalog client script (onchange) and onchange field will be the last check box in the script you can loop every value.

 

 

thanks and regards 

Sai venkatesh 

But we don’t know which field (item) the user will select last, so relying on the last checkbox’s onChange event might not trigger the calculation in every case. We’d need a way to recalculate the total whenever any relevant checkbox changes. 

You are correct, so either you can create  multiple  client script and do same action for all. 
OR, you can add price in the variable type specifications like Price if checked. See image for reference.Screenshot 2025-08-16 111616.png

AbhishekLawaniy
Tera Contributor

What I can think of is 
One onChange Client Script for all food items and the discount field
Instead of creating an onChange script for each checkbox, you can use a single onChange script triggered by both the food item checkboxes and the Available Offers field. This script will then iterate through the necessary variables to perform the calculations.

Steps

Identify your variables:

  • Food Item Checkboxes: veg_manchuria_checkbox, chicken_biryani_checkbox, mutton_biryani_checkbox, etc.
  • Price Fields: veg_manchuria_price, chicken_biryani_price, mutton_biryani_price, etc. (These should be single-line text variables and marked as read-only).
  • Available Offers: available_offers (Choice variable with values like '10', '20', '30' for percentage discount).
    Total Bill: total_bill (Single-line text variable, read-only).

Create an onChange Catalog Client Script.

Table: sc_req_item (or the appropriate table for your catalog item if it's a record producer).
Type: onChange
Variable Name: Select one of your food item checkboxes (e.g., veg_manchuria_checkbox).
Applies on: Catalog Item

function onChange(control, oldValue, newValue, isLoading) {
    if (isLoading || (newValue === oldValue && control.name !== 'available_offers')) {
        return; // Don't run on load or if value hasn't changed (unless it's the discount field)
    }

    calculateTotalBill(); // Call the function to perform the calculations
}

// Function to perform the total bill calculation
function calculateTotalBill() {
    var total = 0;

    // Define an array of your food item checkboxes and their corresponding price fields
    // Ensure the variable names here exactly match your Catalog Item variables.
    var foodItems = [{
        checkbox: 'veg_manchuria_checkbox',
        price: 'veg_manchuria_price'
    }, {
        checkbox: 'chicken_biryani_checkbox',
        price: 'chicken_biryani_price'
    }, {
        checkbox: 'mutton_biryani_checkbox',
        price: 'mutton_biryani_price'
    }
    // Add all your food items here following the same structure
    ];

    // Loop through each food item
    for (var i = 0; i < foodItems.length; i++) {
        var item = foodItems[i];
        if (g_form.isVisible(item.checkbox) && g_form.getValue(item.checkbox) == 'true') { // Check if visible and checked
            var price = parseFloat(g_form.getValue(item.price)); // Get the price, convert to number
            if (!isNaN(price)) { // Check if the price is a valid number
                total += price;
            }
        }
    }

    // Apply the discount
    var discountPercentage = parseFloat(g_form.getValue('available_offers')); // Get the discount percentage
    if (!isNaN(discountPercentage) && discountPercentage > 0) {
        var discountAmount = total * (discountPercentage / 100);
        total -= discountAmount;
    }

    // Update the Total Bill field
    g_form.setValue('total_bill', total.toFixed(2)); // Display with 2 decimal places
}

Create separate onChange Catalog Client Scripts
For each food item checkbox:
Table: sc_req_item
Type: onChange
Variable Name: (Each of your food item checkboxes - e.g., veg_manchuria_checkbox)
Applies on: Catalog Item

function onChange(control, oldValue, newValue, isLoading) {
    if (isLoading) {
        return;
    }
    calculateTotalBill(); // Call the common calculation function
}

 

=========================================================
If my response proves useful, please indicate its helpfulness by selecting "Accept as Solution" and " Helpful." This action will support the community. 

Regards,
Abhishek Lawaniyan
=========================================================
If my response proves useful, please indicate its helpfulness by selecting "Accept as Solution" and " Helpful." This action will support the community.