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();
    }


      Zoho Campaigns Resources


        • Desk Community Learning Series


        • Digest


        • Functions


        • Meetups


        • Kbase


        • Resources


        • Glossary


        • Desk Marketplace


        • MVP Corner


        • Word of the Day


        • Ask the Experts


          Zoho CRM Plus Resources

            Zoho Books Resources


              Zoho Subscriptions Resources

                Zoho Projects Resources


                  Zoho Sprints Resources


                    Zoho Orchestly Resources


                      Zoho Creator Resources


                        Zoho WorkDrive Resources



                          Zoho CRM Resources

                          • CRM Community Learning Series

                            CRM Community Learning Series


                          • Tips

                            Tips

                          • Functions

                            Functions

                          • Meetups

                            Meetups

                          • Kbase

                            Kbase

                          • Resources

                            Resources

                          • Digest

                            Digest

                          • CRM Marketplace

                            CRM Marketplace

                          • MVP Corner

                            MVP Corner




                            Zoho Writer Writer

                            Get Started. Write Away!

                            Writer is a powerful online word processor, designed for collaborative work.

                              Zoho CRM コンテンツ








                                ご検討中の方

                                  • Recent Topics

                                  • Add a Way to Duplicate Cards in the Same Canvas (Retain All Settings)

                                    Dear Zoho SalesIQ Team, We would like to request a new feature in Zoho SalesIQ: the ability to duplicate an existing card within the same canvas while retaining all of its information and settings, including conditions, configurations, and display preferences.
                                  • Sales IQ needs to capture both first and last names

                                    Sales IQ chat only has one field for name. When this then syncs with Campaigns, the field populates the "last name" field in Campaigns. However most people fill in the "name" field of Sales IQ with either their full name or their Christian name. This
                                  • Multi-Card Selection and Cross-Zobot Copy-Paste Functionality

                                    Dear Zoho SalesIQ Team, We’d like to suggest a productivity-enhancing feature for the Zobot builder in Zoho SalesIQ: the ability to select multiple cards (modules) at once using a selection area, and then copy-paste them either within the same canvas
                                  • Personal Link / Meeting ID

                                    with zoho meetings do I have my own personal link to my 'meeting space' ? I have an email template in Zoho CRM which confirms people's appointment with me, I would like to include the link to my Zoho Meetings so that they have it in advance. How do I
                                  • Ability to Initiate WhatsApp Template Messages in Zoho SalesIQ Without Preexisting Chat

                                    Hi Zoho SalesIQ Team, I hope you're doing well. I understand that with the WhatsApp integration in SalesIQ, clients can contact us via WhatsApp, and we can use WhatsApp templates to send messages outside of the 24-hour window by reopening an existing
                                  • Related Lists filter

                                    I have Contacts showing in our Accounts module. I customized the Contacts module with an Employment Status field, with the following picklist options: "Primary Contact", "Secondary Contact", "Active Staff(not a main contact)", and "No longer employed".
                                  • Adding Overlays to Live Stream

                                    Hello folks, The company I work for will host an online event through Zoho Webinar. I want to add an overlay (an image) at the bottom of the screen with all the sponsors' logos. Is it possible to add an image as an overlay during the live stream? If so,
                                  • Making money out of Zoho Sheets - How?

                                    Hello, Suppose I come up with a brilliant Zoho Sheet that I want to sell to other people, can I do this? How? Thanks.
                                  • How Do I Refund a Customer Directly to Their Credit Card?

                                    Hi, I use books to auto-charge my customers credit card. But when I create a credit note there doesn't seem to be a way to directly refund the amount back to their credit card. Is the only way to refund a credit note by doing it "offline" - or manually-
                                  • Mobile Display Issues on Zoho Sites After Recent Update

                                    Hello! I’m currently facing an issue with my Zoho website that I created for my small business. After the recent updates, I’ve noticed that my site is not displaying correctly on mobile devices. Specifically, the layout appears distorted, and some elements
                                  • Can i set per-client hourly rate in Zoho Desk and not to correct the calculation on invoice?

                                    We use Zoho Desk to run one ticket per client per month. All time entries go to the ticket, we have to enter hourly rate manually and then correct it when we do the invoicing at the end of the month. So, our workflow is as following: I worked for 30 minutes,
                                  • Unable to add Agents

                                    I am trying to add agents to my account. While filling the details and sending invitation, the system mentions that invitation is sent. But no email is received on the user side. I have tried this multiple times and have also checked Spam and other
                                  • How to add new widgets?

                                    Searched and searched and cannot find anywhere. Why is everything so hidden in zoho! Why is there not a button right here that allows me to create a new one, why is it buried somewhere else! Zoho's UI is so infuriating
                                  • Submit Ticket from Custom Form on Website

                                    Hi I would like to create new tickets from our custom form on our website including some custom fields like serial number. I would prefer PHP to create the ticket. I know there is the Zoho webform but we would like to create our own. I have now read into the API and with AuthToken this would work with PHP but it is deprecated  and will not be supported any more in the future, so this not an option. OauthToken on the other hand needs an interaction from the ticket creator (customer) which we would
                                  • Customising Sign Up Page in Zoho Help Centre Sandbox

                                    Hi, I would like to customise the Sign Up page in my Help Centre Sandbox Environment but when I try to access it I get this message: What setting or permission do I need to achieve this? Many thanks, Kunal
                                  • Sort data in Pivot Table

                                    Is it possible to sort by a data field. I can gruop and filter, but I culdn't find how to sort the results. Tank You.
                                  • How to interact webhooks with Creator?

                                    How can I interact webhooks from external websites with Zoho Creator?  I'd like to get notifications from external websites (Stripe, Zoho Subscription, etc.) These notifications are coming as HTTP POST request from those servers, on maybe daily, monthly or based on any events.  How should I prepare my app in creator to receive these requests? Where and how to should I program in Deluge if I'd like to add some part of the JSON/XML data to my form?  Thank you BR, Balazs
                                  • No Experiment Visitors

                                    I have an experiment running for five days. PageSense web analytics data shows the page is getting visitors, but the experiment data itself says zero visitors. I am in trial mode, not sure if that's related. A week ago, I contacted support through chat
                                  • How do I get at the data in "Partially Saved Entries"?

                                    Hi, Zoho Newbie here - I'm helping to support an existing Zoho installation, so this is all a bit new to me. I have to say, I'm liking what I've seen so far! We've just spotted that we have a number of respondents to our forms who don't end up submitting
                                  • SOLVED: Stopping Multiple Invitations when sync with Google Calendar

                                    I wanted to share this solution as I wasn't able to find it when searching through the Zoho community and via web search. The issue: When requestor books a meeting through Zoho Bookings, the requestor receives a confirmation email from both Bookings and
                                  • Help Needed with Creating Close % Reporting

                                    Now that our company has a good data set to work with we want to use ZCRM reports ways to track the performance metrics we have established. Specifically, I want to be able to calculate closing % for individual salespeople and individual support people.
                                  • Restricting Calendar View to Working Hours

                                    Hi: I'm trying to implement a calendar which displays all of my customer appointments.  Currently, the calendar shows all 24 hours of the day.  Is there a way to restrict the hours to simply the times my business is open? Thanks!
                                  • Static Prefill URLs Functionality in the App

                                    Hi, It would be great to be able to use the same functionality within the App, so create the Static Prefill URL as today and be able to use online as today, and then have an area within the App showing these Entries that can be pressed and opens the form
                                  • Outbound Gateway

                                    Hi, Is it possible to configure the Outbound Gateway to route external domains only and keep inter-domain emails locally delivered? When one of my users sends an email to another user within our own domain, I want user1@mydomain.com to user2@mydomain.com not to exit. However, if anyone within our domain sends to an external address, I want that email to be routed using the Outbound Gateway. Thanks. P.
                                  • Free Webinar : Unlock AI driven business insights with Zoho Inventory + Zoho Analytics

                                    Are you tired of switching between apps and exporting data to build customized reports? Say hello to smarter & streamlined insights! Join us for this exclusive webinar where we explore the power of the Zoho Inventory–Zoho Analytics integration. Learn
                                  • Delivery Note Delivered item must be reduce in inventory stock

                                    When I create any Delivery note with product like mobile In our stock if it was 10 Unit I sold thru invoice, 4 unit And thru Delivery note, 2 Unit and I also change Delivery note status as delivered So in my stock it should display remaining 4 unit But write now it display 6 unit only. Please help me for that Because when I creating new invoice it display 6 unit in stock but actually in my physical stock its only 4. So I miss guide with stock display
                                  • Adding bills from docs *** Internal Error ***

                                    Same internal errors in Chrome & Edge !
                                  • Response time when adding customers to the database is increasing over time.

                                    Response time when adding customers to the ZoHo books database is increasing over time. The response time to retrieve a newly added customer is now 1.5 to 2 minutes. The database has approximately 2,000 customers. I think you need to reorganise the
                                  • Excluded transactions in Banking

                                    Why are the payees not checked when 2 payments are for the same amount to avoid exclusion? If there are 2 ( or more ) payment amounts which are the same then they are automatically excluded, this should not happen unless the payee names are the same
                                  • Introducing Zia AI in Zoho Show

                                    AI is no longer a distant concept. It’s one of our everyday tools, from answering casual questions to generating critical business documents. And presentations are one area where AI can be especially helpful. At Zoho Show, we’ve been deliberate in how
                                  • Plug Sample #10 - Simplify Ticket Management (Zoho Desk) with Chatbots

                                    Hi everyone! We're here with another simple yet effective plug for your chatbot to integrate with Zoho Desk. When a customer reports an issue/request during chat, it's logged as a ticket on Desk. When they return for updates, you end up searching through
                                  • Trigger a field rule when Choice Availability reaches 0

                                    First of all, thanks for shipping the new Choice Availability counter. It solves the basic “stop over-booking” problem. What’s missing, though, is a way to react when an option is sold out. Right now we can only disable/hide the choice; we can’t fire
                                  • Unattended Access on Android without Play Store

                                    I'm testing Zoho Assist for remote config and maintenance of our IoT devices. The devices are running Android 8.1 and do NOT have Google Play Store installed, nor can it be installed. I've been able to install Zoho Assist on the devices and load the enrollment
                                  • Zoho People > Performance Management > Appraisal cycle

                                    Hello All I am using this 2 users to test out how it work on Performance Management User 1 - Reportee User 2 - Reporting Manager : Li Ting Haley User 1 : Self Appraisal Error How do i fix this error?
                                  • What's New - June 2025 | Zoho Backstage

                                    Plans change. People cancel. Tickets get handed off. It happens, and we understand. As an organizer, you need tools that offer flexibility for attendees while protecting your event’s integrity. That’s why we’ve built features to help you manage these
                                  • Include Article Sync Details in SalesIQ–Desk Integration Notification Email

                                    Dear Zoho SalesIQ Team, Greetings, We are using the integration between Zoho SalesIQ and Zoho Desk to sync articles from the Zoho Desk Knowledge Base into SalesIQ. As part of this integration, we receive the following email notification: "Your scheduled
                                  • Naming a Visitor in SalesIQ Messes up First and Last Name

                                    When I go to Visitor History to manually associate a visitor with a known contact, I press the pencil symbol next to the system-generated ID number. I enter first and last name, then email. Looks good so far. However, when it syncs with CRM, first name
                                  • Partial Sync

                                    Hi, got an issue with syncing cards across windows app, web app and iphone app. If I create a card and add some text content then everything syncs across all platforms ok. If I create a card and add an attachment, be it pdf, jpg or movie then the card
                                  • Related activity records for custom modules

                                    For default modules in CRM, whenever I create a task for a contact, the task also appears in the record for the parent account. How do I replicate this with custom modules? My specific situation is that I have a custom module as a child module to Accounts.
                                  • Why Do My Portal Users Can't See Any Data in Reports

                                    In My zoho crm i have created a button automation which basically is it converts a quote into invoice and sales order , so initially when a person who is my app user submits a quotation form it goes into quote module and record is created and in each
                                  • Next Page