User Tips: Adding Multiple Products (Package) to a Quote v2.0 (with Client Script)

User Tips: Adding Multiple Products (Package) to a Quote v2.0 (with Client Script)

This solution is an improvement on the original idea which used deluge. My solution was posted in the comments are: https://help.zoho.com/portal/en/community/topic/adding-multiple-products-package-to-a-quote

The updated version uses client script instead of deluge.

Hopefully this might help a few people. It helps our reps speed up the process of creating quotes and quoting accurately.

Details below:


Problem:

We run numerous manufacturer promotions with various bundled items and discounts. Reps struggle to remember all details, leading to incorrect discounts on quotes.


Solution

I created a custom module for Product Packages. For each promotion, we create a "Package" including all products, discounts, and start/end dates. A quote lookup field allows users to select a package, automatically adding the related products with accurate pricing and information.

When a user selects a package, a client script retrieves all related products and discounts, adding them to the quote. The lookup field is then reset for additional product entries.

Some fields on the package layout include:

  1. Promotion type
  2. Status
  3. Start / End dates for the promotion. 
  4. Pop-up message field if we want to show the rep a message when quoting the package

I also have a workflow that sets the package to “Expired” when the record expiration date hits. The lookup is filtered in the quotes module to only show “Active” packages.

In Action (with lookup field to the package module):



The Setup:
Create a custom module “Package Items”. Add the fields as below. 



Additional Info
1. I also use client script to hide the “Auto-Quote” field when in a standard view page
2. When I name a package, a deluge script runs to append the Package ID number which is an auto-number field.


The Code: 

  1. try {
    // List of funny loading messages
    var loadingMessages = [
    "Cranking up the quote machine...",
    "One sec... just stepped out for coffee.",
    "Hold tight! The hamsters are running the wheels.",
    "Almost there... giving it a little extra attention.",
    "Loading... probably faster than your internet speed.",
    "Please hold while we make magic happen.",
    "Just a moment... our servers are stretching their legs.",
    "Your patience is appreciated... and rewarded!",
    "Brewing up your quote right now...",
    "Give us a second... we're flexing our technical muscles.",
    "Our system is doing some yoga... stay calm!",
    "Loading... don't worry, it's not stuck!",
    "Fetching your data... hopefully with no detours!",
    "Keep calm and let us handle the rest.",
    "Processing... taking a coffee break, be right back!",
    "Stay tuned... greatness is loading.",
    "Our system is running... faster than a cheetah!",
    "Looks like you're going all in on this quote!",
    "Getting things ready... just need a moment.",
    "Hold on... we're aligning some stars for you.",
    "Please wait... we're feeding the server squirrels.",
    "One moment... your quote is coming fresh out of the oven.",
    "Loading... just making sure everything is perfect!",
    "Generating your quote... thanks for your patience!",
    "Almost there... your quote is worth the wait!"
    ];

    // Select a random message from the list
    var randomMessage = loadingMessages[Math.floor(Math.random() * loadingMessages.length)];

    // Log the entire value object to see its structure
    log("Full value object: " + JSON.stringify(value));

    // Ensure value.id is defined before proceeding
    if (!value || !value.id) {
    log("No product selected or value.id is undefined");
    return; // Exit the script quietly since no valid product was selected
    }

    // Show loader
    ZDK.Client.showLoader({ type: 'page', template: 'vertical-bar', message: randomMessage });

    // Extract the product ID and name from the value passed in
    var packageId = value.id;
    var packageName = value.name;
    log("Product ID: " + packageId);
    log("Package Name: " + packageName);

    // Get the subform field from Quotes module
    var quotedItemsSubform = ZDK.Page.getField("Quoted_Items");

    // Fetch product information for the package ID
    var packageDetails = ZDK.Apps.CRM.Auto_Quote_Packages.fetchById(packageId);


    var packageStatus = packageDetails.Status; // Active or Expired.
    var popUpMessage = packageDetails.Pop_Up_Message; // Check the package for any Pop-up message we want to show
    log("Package Details: " + JSON.stringify(packageDetails));
    log("Package Status: " + packageStatus);
    log("Pop-Up Message: " + popUpMessage);

    // Initialize array for existing line items.
    var existingLineItems = quotedItemsSubform.getValue() || [];
    log("Existing line items: " + JSON.stringify(existingLineItems));
    //
    // Only include rows with products. Excude any blank rows from the quote
    var filteredExistingLineItems = existingLineItems.filter(function(item) {
    return item.Product_Name && item.Product_Name.id;
    }).map(function(item) {
    return {
    id: item.Product_Name.id // Include only the item ID
    };
    });
    log("Filtered existing line items: " + JSON.stringify(filteredExistingLineItems));

    // Array to hold new line items we are adding
    var newLineItemArray = [];

    // Check if package is active and populate new line items
    if (packageStatus === "Active") {
    var packageItems = packageDetails.Package_Details;
    packageItems.forEach(function(item) {
    var productLineItem = {
    Product_Name: {
    id: item.Item_Code.id,
    name: `${item.Item_Code.name} (${item.Item_Name})`
    },
    Product_List_Price: item.Item_Price,
    Description: item.Item_Description,
    List_Price: item.Item_Price,
    Quantity: item.Item_Quantity ?? 1, // Default to 1 if Qty is null or undefined
    Discount: Math.abs(item.Item_Discount ?? 0) // Get the discount or default to 0 if null
    };
    log("New product line item: " + JSON.stringify(productLineItem));
    newLineItemArray.push(productLineItem);
    });
    } else {
    // Show error message if the package is not active
    // My layout to only show Active items but if you don't do that this solves it.
    ZDK.Client.showMessage('This package / promo is no longer active. Please contact the admin for details.', { type: 'error' });
    ZDK.Client.hideLoader();
    return; // Exit the script since the package is not active
    }

    // Combine existing line items with new line items
    var updatedLineItemArray = filteredExistingLineItems.concat(newLineItemArray);
    log("Updated line items array: " + JSON.stringify(updatedLineItemArray));

    // Add all updated items to the Quotes page
    quotedItemsSubform.setValue(updatedLineItemArray);

    // Reset the pick list field so user can re-use
    ZDK.Page.getField("Auto_Quote").setValue(null);

    // Hide loader
    ZDK.Client.hideLoader();

    log("Final updated line items: " + JSON.stringify(updatedLineItemArray));

    // Function to show confirmation and number of items added back to the user
    var showSuccessMessage = function() {
    ZDK.Client.showMessage(`${value.name} selected. ${newLineItemArray.length} items added successfully.`, { type: 'success' });
    };

    // Function to show popup message and then success message
    var showAlertAndSuccess = function(message, heading, buttonText) {
    ZDK.Client.showAlert(message, heading, buttonText);
    showSuccessMessage();
    };

    // Check for pop-up message and show alert if it exists
    if (popUpMessage) {
    showAlertAndSuccess(popUpMessage, "Important Information", "Got It!");
    } else {
    // No pop-up message, show the success message
    showSuccessMessage();
    }
    } catch (error) {
    // Log the error
    log('Error: ' + error.message);

    // Show error message
    ZDK.Client.showMessage('An error occurred while adding items. Please try again.', { type: 'error' });

    // Hide loader
    ZDK.Client.hideLoader();
    }

    • Recent Topics

    • My email is blocked from sending

      I get this message when I try to send any message .. > Unable to send message, Reason 554 5.1.8 Email Outgoing Blocked We have urgent emails to send and the issue continues to persist from yesterday. Please help us with this issue as soon as possibl
    • [WEBINAR] Smooth year-end closure with Zoho Books (KENYA)

      Hello there, This webinar is for all Kenyan businesses looking to wrap up their financial year smoothly! Join our free session to learn how Zoho Books can simplify your year-end process. What to expect from this webinar: - All the latest updates in Zoho
    • cannot recieve or send emails

      we are not recieving or cannot send emails.Shows sysytem error
    • Zoho Sites - contact us form

      I have added a contact us form to my website. I wanted to change the layout so I deleted the section of Contact Us form. When I again try to add the section of Contact Us form, it shows error that "This form already exists on this page."  I am unable
    • switching from POP3 to IMAPI do I need to change settings in Web email?

      hi so I am using Outlook with My Zoho mail, also have Verizon email /AOL. they no longer support POP3 and said imapi is much better, so I want to switch my ZoHo to imapai. I googled and it said i need to change it in my account....i looked at my account
    • What functionality is new in the Z025 Spaces UI dashboard compared to the previous Zoho One dashboard?

      My company is interested in creating a revamped dashboard this coming year, and are trying to weigh different platform options. The new Spaces UI is said to be a more "feature-rich" dashboard experience than the previous. Could a developer please explain
    • Collections Management: #5 Convenience on Offer, using Self-Checkout

      "Is this the right page? Oh, now, it wants my address again. Why am I being redirected?" These were the exact thoughts running through Karan's mind as he tried to subscribe to an application he genuinely liked. He clicked "Buy Now", expecting a quick
    • Uploading a signed template from Sign to Creator

      Good day, Please help me on how to load a signed document back into Creator after the process has been completed in Sign. Below is the code that I am trying, pdfFile = response.toFile("SignedDocument_4901354000000372029.pdf"); info pdfFile; // Attach
    • PROBLEMA

      Salve, non riesco a inviare email, e mi esce una tabela errore temporaneo. come posso risolvere il problema ?
    • Tip #50- A Closer Look at the Unattended Access Dashboard- 'Insider Insights'

      Having complete visibility and quick access to everything you need certainly makes managing multiple remote devices a lot easier, and that is precisely what the Unattended Access Dashboard in Zoho Assist is designed to offer. Once you go to the Unattended
    • How to update custom multi-user field in Zoho Projects?

      I'm trying to update custom multi-user fields in Zoho Projects via a Deluge function in CRM. The code I have so far is below. It works for updating standard project fields and single-line custom fields, but it does not work to update multi-user fields.
    • Tip of the Week #75– Manage your social media messages from a single shared inbox.

      Are you tired of jumping between apps or browser tabs to reply to your business's Facebook and Instagram DMs? Handling customer messages on social media might seem simple, but switching between multiple platforms can easily lead to lost messages, duplicate
    • Zoho Map integration tasks have changed - you need to "Locate all instances of Zoho Map integration tasks in your Deluge scripts by searching for the v1 marker... before 16 January 2026"

      The Zoho Map deluge integration task has been changed (as at 21 October 2025) to provide a more structured, JSON-like response. This change affects all three Zoho Map integration tasks (Geocode, Reverse Geocode, and Distance Between). More details can
    • Using files from Zoho CRM in Gemini/ChatGPT/Claude

      Hi all, I’ve got subscriptions to Gemini and a few other AI tools which I use for tasks like data enrichment, email composition, etc. In our workflow, we often receive various documents from clients — such as process workflows, BRDs/requirement documents
    • Zoho Analytics & Zoho Creator - Modified Time value

      I'm trying to use the Zoho Creator system field 'modified time' in Zoho Analytics, but it's consistently showing 12 hours 'out' In Zoho Creator In Zoho Analytics Is this a constant difference that I just need to correct with a timezone change - or is
    • Zoho CRM - Option to create Follow-Up Task

      When completing a Zoho CRM Task, it would be very helpful if there was an option to "Complete and Create Follow-Up Task" in the pop-up which appears. It could clone the task you are closing and then show it on the screen in edit mode, all the user would
    • Portal For Different Apps

      I found some older threads on this but didn't see anything very recent. I'm new to Zoho One so forgive me if my terminology is off a bit. I was hoping set up a single point of entry into Zoho One. So, many of the apps could be found in one single place
    • Calls undetected

      Zoho Voice records indicate my last call ended at 6:00 PM. All incoming and outgoing calls occurred between 6:00 PM and 7:00 PM.
    • Unable to Select Authenticated Domain as Sender

      We’ve already authenticated our domain, but it’s still not appearing in the sender list when we try to run a campaign. Could you please check what might be causing this issue?
    • Forever FREE Business Email with Zoho Mail

      Forever FREE Business Email with Zoho Mail: is it available?
    • Zoho Projects - Project Details on the Project Menu

      Hi Project's team, I've helped may businesses setup and use Zoho Project and one thing I see time and time again is confusion on where to find the Project Details information. I would be much more intuitive if Project Details was on the menu before Dashboard.
    • Introducing WhatsApp integration in Bigin

      Greetings! In today's business landscape, messaging apps play a significant role in customer operations. Customers can engage with businesses, seek support, ask questions, receive personalized recommendations, read reviews, and even make purchases—all
    • Zia Conversation Summary: Context at a glance for every customer interaction

      Hello everyone! Every customer conversation tells a story—but in CRM, that story is rarely in one place. A sales rep moving between multiple leads has to reopen long email threads, check call remarks, and revisit meeting notes just to remember what was
    • Zoho Projects - Show Task List as dropdown field on Task records

      Hi Project's Team, I noticed today that there is no field on a task record related to the task list it belongs to. A dropdown would be helpful for quickly moving tasks between lists while in a task. I know that you can go to "Other Actions" and choose
    • Changing the Default Search Criteria for Finding Duplicates

      Hey everyone, is it possible to adjust the default search criteria for finding and merging duplicate records? Right now, CRM uses some (in my opinion nonsensical) fields as search criteria for duplicate records which do nothing except dilute the results.
    • My followed tickets extension is not working under the All departments view

      Hi. I've installed the My followed tickets extension. However, when I try to open the extension under the all departments view, I get the following message: 'Sorry, this extension is not supported in the All Departments view.' How can I solve this p
    • Ticket Time Entry to Timesheet

      The title just about sums it up. I have searched here and not found anything relevant, but If I overlooked, then please set me straight.  We have staff that do nothing but close tickets in desk all day long. These tickets represent their timesheet. Is there a way to have this information sync or for a tech to go into their timesheet themselves and sync it with their tickets of the same timeframe?? We waste a ton of time doing timesheets and the old "Clock in/Clock out" isnt detailed enough for us!!
    • Calls undetected.

      The call is not showing on the call log.
    • Calls undetected

      Zoho is not reading calls made.
    • Multi-currency and Products

      One of the main reasons I have gone down the Zoho route is because I need multi-currency support.  However, I find that products can only be priced in the home currency, We sell to the US and UK.  However, we maintain different price lists for each. 
    • Archiving Contacts

      How do I archive a list of contacts, or individual contacts?
    • Missing information data Zoho inventory

      there some missing data in Zoho inventory connection. pick list stock counts bin location we have requested it via mail and the support team doesn’t gove feedback. has anyone achieve to get these info or to ask other ya les
    • Calendar Events Issues

      Not able to view scheduled events on my calendar
    • Extensions 101 webinar series: Build, integrate, and monetize with extensions

      Attention developers! Are you ready to take your extension development skills to the next level? We're excited to bring back the Extensions 101 webinar series with an expanded lineup of Zoho products and an introduction to more platform features. Last
    • Custom Related List Inside Zoho Books

      Hello, We can create the Related list inside the zoho books by the deluge code, I am sharing the reference code Please have a look may be it will help you. //..........Get Org Details organizationID = organization.get("organization_id"); Recordid = cm_g_a_data.get("module_record_id");
    • Where are recordings stored?

      I have hosted a couple of test meeting, used the "record" button to start and stop the recording but I am unable to find where are those recordings saved?  Can anybody help? Thanks
    • Zoho Desk's integration with Microsoft PowerBI delivers advanced analytics insights

      Hello everyone, Gaining advanced insights through reports and dashboards is one of the critical requirements of every business. In addition to key metrics tracked in Zoho Desk, such as agent performance, SLA adherence, and ticket lifecycle, businesses
    • Create static subforms in Zoho CRM: streamline data entry with pre-defined values

      Last modified on (9 July, 2025): This feature was available in early access and is currently being rolled out to customers in phases. Currently available for users in the the AU, CA, and SA DCs. It will be enabled for the remaining DCs in the next couple
    • IMAP error message in Zoho mail

      I cannot send emails today. Everything fine for years until today. Get a message: "You are yet to enable IMAP for your account. Please contact your administrator". Does anyone know how to correct this?
    • Enhancements to Zoho Map integration tasks

      Hello everyone, We're excited to announce enhancements to the Zoho Map integration tasks in Deluge, which will boost its performance. This post will walk you through the upcoming changes, explain why we're making them, and detail the steps you need to
    • Next Page