Loading...

Reopening Won Quotes in Dynamics 365 Sales Professional / Enterprise (C#)

Reopening Won Quotes in Dynamics 365 Sales Professional / Enterprise (C#)
Featured image of post Reopening Won Quotes in Dynamics 365 Sales Professional / Enterprise (C#)

After you’ve spent any length of time working with the out of the box sales process within Dynamics 365 Sales Professional / Enterprise, you get used to some of the behavioural quirks that can commonly cause you challenges during an implementation. A prime candidate for consideration here concerns the various types of tables used by the application. When we consider these in detail, such as the Opportunity, Quote and Order table, many of the assumptions that we make about how things work are instantly proven wrong, as these tables tend to operate by their own set of rules. For example, the ability to easily map across attributes between the different product line table types (Opportunity Product, Quote Product etc.) becomes a challenge; we must instead revert to using custom code instead to satisfy this requirement. Little things like this can exasperate both new and long-time users of the application and can often be quite frustrating when explaining to organisations using the software. 😅 Notwithstanding these gripes, I still do genuinely believe the Dynamics 365 Sales platform provides a solid base for organisations to leverage out of the box functionality, with the ability to customise further, as needed. And, when we start to bring into the equation more advanced capabilities, via things such as custom pricing plug-ins, you begin to move to an entirely new level when it comes to what we can do with this application.

A particularly annoying behaviour quirk I dealt with recently involved Quotes marked as Won in the system. The organisation I was working with needed to, on occasions, modify details of a Won Quote after the fact. For example, if the salesperson included the wrong item or the customer changed their order after confirming it. As we can observe in the below screenshot, we have no option on the ribbon to reactivate the Quote once Won in the application:

The only “out of the box” way of dealing with this was to create and re-input all details into a new Quote; not a viable and time-effective solution. Fortunately, there is a faster way we can achieve the objective by working through the following outline steps:

  1. First, we need to change the Status & Status Reason of the Quote back to Draft & In Progress.
  2. After we have made modifications to the Quote, it needs to be set as Active again.
  3. Once Active, the Quote then must be closed as Won. Microsoft wraps the logic for this within the WinQuote action, which we can call via the SDK or against the Microsoft Dataverse Web API.

These steps should be achievable via either a classic workflow or a Power Automate cloud flow automation, which would typically be our first preference for a requirement like this. However, in our case, we wanted to call these steps as part of a Custom API definition, which could then be called via a JavaScript action on a Ribbon button, similar to how I’ve described previously on the blog. And, most crucially, we needed all steps to be completed synchronously. So, given these requirements, we had to look at a solution leveraging C# instead.

With all of this in mind, let’s jump into the reason why you’re probably reading this post. 😉 To open a Won Quote using C#, we would need to write and execute the following code:

//TODO: Implement code to generate your IOrganizationService reference. For plug-ins, this would look something like this:
//IOrganizationServiceFactory serviceFactory = serviceProvider.GetService<IOrganizationServiceFactory>();
//IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);

Guid quoteID = new Guid("9cc66ad5-2506-4394-854d-f60c35185d96");
Entity quote = new Entity("quote", quoteID);
quote["statecode"] = new OptionSetValue(0); // Draft
quote["statuscode"] = new OptionSetValue(1); // In Progress
service.Update(quote);

Then, once we’re ready to return the Quote to its previous state, we’d then run the following code to re-close the Quote. Note in particular, at this stage, we need to execute two separate actions and ensure they are completed successfully:

//TODO: Implement code to generate your IOrganizationService reference. For plug-ins, this would look something like this:
//IOrganizationServiceFactory serviceFactory = serviceProvider.GetService<IOrganizationServiceFactory>();
//IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);

// We execute everything in a transaction, so we can rollback cleanly on failure
ExecuteTransactionRequest transactionRequest = new ExecuteTransactionRequest()
{
    Requests = new OrganizationRequestCollection(),
    ReturnResponses = true,
};
ExecuteTransactionResponse transactionResponse;

Guid quoteID = new Guid("9cc66ad5-2506-4394-854d-f60c35185d96");

// First, we need to Activate the Quote ...
Entity quote = new Entity("quote", quoteID);
quote["statecode"] = new OptionSetValue(1); // Active
quote["statuscode"] = new OptionSetValue(2); // In Progress

UpdateRequest updateRequest = new UpdateRequest()
{
    Target = quote,
};

transactionRequest.Requests.Add(updateRequest);

// ...with this done, now we can re-close the Quote as Won
Entity quoteClose = new Entity("quoteclose");
quoteClose["subject"] = "Quote Close" + DateTime.Now.ToString();
quoteClose["quoteid"] = quote.ToEntityReference();

WinQuoteRequest winQuoteRequest = new WinQuoteRequest()
{
    QuoteClose = quoteClose,
    Status = new OptionSetValue(-1),
};

transactionRequest.Requests.Add(winQuoteRequest);

transactionResponse = (ExecuteTransactionResponse)service.Execute(transactionRequest);
tracer.Trace($"Quote ID {quoteID} closed as won successfully!");

As stated earlier, if there wasn’t a need to execute these actions synchronously, then leveraging Power Automate cloud flows would be something I’d actively encourage instead, as both the ability to update and call action steps are supported via this tool. So before you act too gung-ho with the above, validate your approach against the requirements you are working against.

Regardless of the precise approach you take, it is a minor point of frustration that these types of steps are not natively supported within Dynamics 365 Sales. I understand why the system behaves like this, and there are arguable benefits to having a Quote locked after it’s been approved. However, I imagine the ability to make quick edits to a Won Quote is a common requirement across many different organisations, and expecting users to have to go through raising an entirely new Quote is both impractical and ludicrous in equal measure. It’s good to know that the underlying platform supports us in building workarounds such as this so that we are not left entirely adrift with a system that must fit around the business instead of the other way around.

Published on:

Learn more
The CRM Chap
The CRM Chap

Anything and everything to do with the #PowerPlatform, #MSDYN365, #Azure and more!

Share post:

Related posts

Exploring the Differences: Managed vs. Unmanaged Solutions in Dynamics CRM/Dataverse

In Dynamics CRM/Dataverse, solutions are central to Application Lifecycle Management (ALM), providing a structured way to manage, package, and...

9 days ago

Effective Strategies for Debugging Plugins in Dynamics CRM

In a recent interview, I was asked about debugging plugins in Dynamics CRM. The interviewer specifically wanted to know my approach to plugin ...

11 days ago

New Lead Qualification Experience – Dynamics 365 Sales

To enable the new lead experience, navigate to App Settings >> Lead + opportunity management in the Sales Hub App. On enabling it, we ...

1 month ago

Get AI Generated 360-Degree View of Account Summary in Dynamics 365 Sales [PREVIEW]

Navigating the demanding landscape of sales can be quite a challenge. But the latest release of Microsoft Dynamics 365 Sales is set to revolut...

1 month ago

Five Exciting New Features in Dynamics 365 Sales Wave 1 Release 2024

Introduction Curious about what’s new in Dynamics 365 Sales for 2024? The Wave 1 Release is packed with exciting newfeatures… The post F...

2 months ago

Is Microsoft Dynamics CRM Affordable for Small Nonprofits?

Satish Reddy By Satish Reddy | Reading time 6 mins When considering a CRM solution, affordability is often a primary concern for small no...

2 months ago

How Microsoft Dynamics CRM Services Helps a Startup Nonprofit

Satish Reddy By Satish Reddy | Reading time 6 mins For startup nonprofits, the right Customer Relationship Management (CRM) system can be...

3 months ago
Stay up to date with latest Microsoft Dynamics 365 and Power Platform news!
* Yes, I agree to the privacy policy