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.
GenerateInvoiceFromOpportunityRequest
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;
}
}
}