Generate Invoice from Opportunity when Closing as Won

Sales process is one of the main OOTB business processes in Dynamics CRM. During the sales process Opportunities can be created from Leads (Potential Customers) and opportunities contain opportunity products. From opportunities, quotes can be created, orders can be created from quotes and then invoices can be created from orders.


In this post let’s see how to generate invoice from opportunity using code and overcome issues when getting the OpportunityId.

CRM SDK provides few Methods to Generate Quotes, Orders and Invoices programmatically from Opportunity at any event. Following table shows the Requests and their descriptions that we can use to generate Quotes, Orders and Invoices from Opportunity.

Message Description
GenerateQuoteFromOpportunityRequest Generates a quote from an opportunity.
GenerateSalesOrderFromOpportunityRequest Generates a sales order from an opportunity.
GenerateInvoiceFromOpportunityRequest Generates an invoice from an opportunity.

Invoice can be created when the Opportunity closes as won and Plugin is the ideal solution to create the invoice (or Quote or Order) from the Opportunity.


Inside the plugin body, GenerateInvoiceFromOpportunityRequest can be executed and can get the response with the newly created invoice id.

// Prepare Generate Invoice from Opportunity Request
GenerateInvoiceFromOpportunityRequest generateInvoiceFromOpportunityRequest = new GenerateInvoiceFromOpportunityRequest();

generateInvoiceFromOpportunityRequest.OpportunityId = opportunityId;
generateInvoiceFromOpportunityRequest.ColumnSet = new Microsoft.Xrm.Sdk.Query.ColumnSet(true);

// Generate the Invoice
GenerateInvoiceFromOpportunityResponse generateInvoiceFromOpportunityResponse = (GenerateInvoiceFromOpportunityResponse)localContext.OrganizationService.Execute(generateInvoiceFromOpportunityRequest);



Plugin step has been created as follows to trigger the plugin code when the opportunity is winning. But when reading the OpportunityId from the plugin execution context, we cant just read it using “PrimaryId”.















OpportunityClose Entity

OpportunityId can be read using OpportunityClose entity created when wining (Closing as Won \ Closing as Lost) as follows;

Guid opportunityId = Guid.Empty;

if (localContext.PluginExecutionContext.InputParameters.Contains(“OpportunityClose”) &&
localContext.PluginExecutionContext.InputParameters[“OpportunityClose”] is Entity){
Entity entity = (Entity)localContext.PluginExecutionContext.InputParameters[“OpportunityClose”];

if (entity.Attributes.Contains(“opportunityid”) &&
entity.Attributes[“opportunityid”] != null){
EntityReference entityRef = (EntityReference)entity.Attributes[“opportunityid”];

if (entityRef.LogicalName == “opportunity”){
opportunityId = entityRef.Id;


Author: Indika Abayarathne

MSc in IT [University of Colombo] Solutions Architect | Consultant Technologies: Power Platform | Dynamics CE | Azure

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: