Disqualify Single or Multiple Quotes in Dynamics 365 with One Click! - CloudFronts

Disqualify Single or Multiple Quotes in Dynamics 365 with One Click!

If you’ve ever needed to mark multiple quotes as lost in Dynamics 365, you know the default “Close Quote” dialog can be slow and repetitive.
In my recent project, the sales team wanted a faster way, one click from the main Quotes view, to disqualify single or multiple quotes, without opening each one or clicking through extra prompts.

Using the out-of-the-box CloseQuote action, a small JavaScript function, and a custom Ribbon Workbench button, I built exactly that. Here’s how.

Why I Needed This

Our sales team often manages multiple quotes at once. The standard process meant:

  1. Open each quote individually
  2. Click “Close Quote”
  3. Fill in the dialog
  4. Save and repeat for the next one

It was time-consuming, especially for bulk operations. We needed a quick, grid-based action that would:

  1. Set quotes to Closed – Lost status
  2. Work for single or multiple selections
  3. Refresh the grid automatically

Step 1 – Using the OOB CloseQuote Action

Dynamics 365 provides a built-in CloseQuote bound action that changes the state and status of a quote to closed. Instead of creating a custom action, I decided to call this OOB action directly from JavaScript.

Step 2 – JavaScript to Call the OOB Action

Here’s the function I wrote to handle both single and multiple quotes:

function disqualifyQuotes(selectedControl) {
    // Get the IDs of the records selected in the grid
    var ids = selectedControl.getSelectedIds();

    // If no records are selected, show a message and stop execution
    if (!ids.length) {
        Xrm.Navigation.openAlertDialog({ text: "Please select at least one quote." });
        return;
    }

    // Show a progress indicator while processing
    Xrm.Utility.showProgressIndicator("Disqualifying quotes...");

    // Create an array of requests to process each selected record
    var requests = ids.map(function (id) {
        
        // Create the payload for the CloseQuote action
        var quoteClose = {
            "quoteid@odata.bind": `/quotes(${id.replace(/[{}]/g, "")})`, // Bind to the Quote record
            subject: "Quote closed as Lost", // Subject shown in quote close activity
            description: "Disqualified via custom script" // Optional description
        };

        // Build the request object for the OOB CloseQuote action
        var request = {
            QuoteClose: quoteClose,
            Status: 979570003, // Status Reason: Lost
            getMetadata: function () {
                return {
                    boundParameter: null,
                    parameterTypes: {
                        QuoteClose: { typeName: "Microsoft.Dynamics.CRM.quoteclose", structuralProperty: 5 },
                        Status: { typeName: "Edm.Int32", structuralProperty: 1 }
                    },
                    operationType: 0,
                    operationName: "CloseQuote" // OOB action name
                };
            }
        };

        // Return the execution promise for this request
        return Xrm.WebApi.online.execute(request);
    });

    // Execute all requests and handle the responses
    Promise.all(requests)
        .then(function () {
            // Success: show confirmation and refresh the grid
            Xrm.Navigation.openAlertDialog({ text: "Quotes disqualified successfully." });
            selectedControl.refresh();
        })
        .catch(function (err) {
            // Error handling
            Xrm.Navigation.openAlertDialog({ text: "Error: " + err.message });
        })
        .finally(function () {
            // Close the progress indicator
            Xrm.Utility.closeProgressIndicator();
        });
}

Step 3 – Adding the Ribbon Button in Ribbon Workbench

  1. Open Ribbon Workbench and load the Quote entity.
  2. On the Quote Home Grid, I added a new custom button labeled Close Quote As.
  3. Unlike the out-of-the-box (OOB) Close Quote option — which typically has a fixed dialog — I enhanced this button with a dropdown menu containing multiple closure reasons tailored to our business needs. The dropdown allows users to directly choose from predefined statuses such
    • Expired
    • Not Competitive
    • Job Cancelled
    • Domestic
    • Not as Spec
  4. This approach streamlines the process by letting sales representatives select the appropriate closure reason in one click from the grid, without navigating through additional dialogs. It also ensures consistency in status values while providing more flexibility than the default OOB functionality.
  5. Assign the JavaScript library containing the disqualifyQuotes function.
  6. Pass SelectedControl as the parameter.
  7. Publish the changes.

Now, the button will be available directly on the Quotes view.

Step 4 – Testing the Feature

  1. Navigate to the Quotes view in Dynamics 365.
  2. Select one or more quotes.
  3. Click the ‘Close Quote as’ button.
  4. The status of selected quotes changes to Closed – Lost, and the grid refreshes immediately.

This reduced what was previously a multi-click, per-record task into a single action for any number of quotes.

Why This Works Well

  • No custom server-side logic – leverages a tested, built-in Dynamics action.
  • Bulk friendly – works for multiple records at once.
  • Time saving – ideal for busy sales teams handling multiple opportunities.
  • Easy to maintain – no extra workflows or plugins required.

To conclude, by combining the OOB Close Quote action with Ribbon Workbench, I could instantly disqualify quotes from the main grid, saving hours over the course of a month.

If you’re looking to simplify repetitive processes in Dynamics 365, start by exploring what’s already available out of the box, then add just enough customization to make it your own.

🔗 Need help implementing a custom button or enhancing your Dynamics 365 sales process?

At CloudFronts, we help businesses design and implement scalable, user-friendly solutions that streamline daily operations and improve adoption. Whether it’s customizing Ribbon Workbench, integrating OOB actions, or building tailored automation, our team can make it happen.

📩 Reach out to us at transform@cloudfronts.com and let’s discuss how we can optimize your Dynamics 365 environment.


Share Story :

SEARCH BLOGS :

FOLLOW CLOUDFRONTS BLOG :


Secured By miniOrange