Asked by:
LINQ group EntityCollection Plugin help...

Question
-
Hi everyone,
I have a plugin that fires on the post operation of the create of a Order.
This plugin retrieves all the order Products associated to that Order and creates a new record in a different entity (premium product)
This plugin is working fine.
However, problem occurs when we can have the same order products associated with an order but with some slight value changes
I do not want to create duplicate records. I want to create a query to combine them based on the same product id.. There are also two date fields (Start, Expiry) in the order product entity. I would like to get the Earliest start date and Latest Expiry date.
For e.g.
Product Name: BOX123.. Start Date: 12/06/1984... Expiry Date: 12/08/2013
Product Name: BOX123... Start Date: 21/03/2013... Expiry Date: 12/08/2015
ProductName: BOX234.... Start Date 12/08/2008.... Expiry Date: 12/08/2002
I want my query to return:
Product Name: BOX123.. Start Date: 12/06/1984.... Expiry Date: 12/08/2015
ProductName: BOX234.... Start Date 12/08/2008.... Expiry Date: 12/08/2002
Here is my code:
namespace MSD.Plugins { using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Microsoft.Xrm.Sdk; using Microsoft.Xrm.Sdk.Client; using Microsoft.Xrm.Sdk.Query; using System.Text.RegularExpressions; using System.Linq; public class PopulatePremiumProduct : Plugin { private readonly string preImageAlias = "PreImage"; public PopulatePremiumProduct() : base(typeof(PopulatePremiumProduct)) { RegisteredEvents.Add(new Tuple<int, string, string, Action<LocalPluginContext>>(40, "Update", "salesorder", ExecutePopulatePremiumProduct)); } protected void ExecutePopulatePremiumProduct(LocalPluginContext context) { if (context == null) { throw new ArgumentNullException("Cannot retrieve CRM organisation"); } if (context.PluginExecutionContext.Depth > 1) { return; } var dataContext = new OrganizationServiceContext(context.OrganizationService); try { var pluginExecutionContext = context.PluginExecutionContext; var tracingService = context.TracingService; Entity entity = (Entity)context.PluginExecutionContext.InputParameters["Target"]; Entity preimage = (context.PluginExecutionContext.PreEntityImages != null && context.PluginExecutionContext.PreEntityImages.Contains(preImageAlias)) ? context.PluginExecutionContext.PreEntityImages[preImageAlias] : null; Entity combinedEntity = CombineEntities(preimage, entity); Entity premiumProductHistory = new Entity("new_premiumproductpurchase"); tracingService.Trace("We Have the Entities"); var orderNo = combinedEntity.Attributes["ordernumber"]; var customer = (EntityReference)combinedEntity.Attributes["customerid"]; var owner = (EntityReference)combinedEntity.Attributes["ownerid"]; OptionSetValue status = (OptionSetValue)combinedEntity.Attributes["statecode"]; //Query to retrieve the order products associated to the order tracingService.Trace("Start of query"); var query = new QueryByAttribute("salesorderdetail"); tracingService.Trace("New Query added"); query.ColumnSet = new ColumnSet(new string[] { "salesorderdetailid", "productid", "new_event", "new_inventory", "productdescription" }); tracingService.Trace("New Query Column set added"); query.AddAttributeValue("salesorderid", combinedEntity.Id); tracingService.Trace("New Query add attribute value added"); tracingService.Trace("We have entity collection"); //If the Order is fulfilled if (status.Value == 3) { tracingService.Trace("Order is Fulfilled"); Entity product = null; Entity bbcEvent = null; Entity inventory = null; Guid newPremiumProductGuid = Guid.Empty; //Loop through the Order products associated to the order foreach (var orderProducts in retrieved.Entities) { tracingService.Trace("Order products " + orderProducts.Id); premiumProductHistory.Attributes["ownerid"] = owner; Entity a = (Entity)orderProducts; if (orderProducts.Contains("productid")) { product = context.OrganizationService.Retrieve("product", ((EntityReference)orderProducts["productid"]).Id, new ColumnSet("name")); tracingService.Trace("Set name of Product already in the system"); premiumProductHistory.Attributes["new_name"] = product.Attributes["name"]; premiumProductHistory.Attributes["new_productid"] = orderProducts.Attributes["productid"]; } //Populate the Write in Product name else { premiumProductHistory.Attributes["new_name"] = orderProducts.Attributes["productdescription"]; } if (orderProducts.Contains("new_event")) { tracingService.Trace("We have the event"); bbcEvent = context.OrganizationService.Retrieve("new_event", ((EntityReference)orderProducts["new_event"]).Id, new ColumnSet("new_startdatetime", "new_enddatetime")); premiumProductHistory.Attributes["new_eventid"] = orderProducts.Attributes["new_event"]; tracingService.Trace("We have set the event to the premium product"); if (bbcEvent.Contains("new_startdatetime")) { tracingService.Trace("We have the start date"); premiumProductHistory.Attributes["new_currentproductstartdate"] = bbcEvent.Attributes["new_startdatetime"]; } if (bbcEvent.Contains("new_enddatetime")) { tracingService.Trace("We have the end date"); premiumProductHistory.Attributes["new_currentproductexpirydate"] = bbcEvent.Attributes["new_enddatetime"]; } } if (orderProducts.Contains("new_inventory")) { tracingService.Trace("We have the inventory"); inventory = context.OrganizationService.Retrieve("new_inventory", ((EntityReference)orderProducts["new_inventory"]).Id, new ColumnSet(true)); if (inventory.Contains("new_grouptier") && inventory.Contains("new_groupnumber")) { premiumProductHistory.Attributes["new_block"] = inventory.Attributes["new_groupnumber"]; } if (inventory.Contains("new_number")) { premiumProductHistory.Attributes["new_seat"] = inventory.Attributes["new_number"]; } if (inventory.Contains("new_row")) { premiumProductHistory.Attributes["new_row"] = inventory.Attributes["new_row"]; } if (inventory.Contains("new_stand")) { //TODO: Need to create a field on the premium product History and Inventory called new_stand premiumProductHistory.Attributes["new_stand"] = inventory.Attributes["new_stand"]; } } if (customer.LogicalName.Equals("account")) { premiumProductHistory.Attributes["new_companyid"] = customer; } else { premiumProductHistory.Attributes["new_contactid"] = customer; } context.OrganizationService.Create(premiumProductHistory); } } } catch (Exception ex) { throw new InvalidPluginExecutionException(String.Format("An error occured Excuting the Plugin {0}{1}{2}", ex.Message, Environment.NewLine, ex.StackTrace)); } finally { //throw new InvalidPluginExecutionException("trace"); context.TracingService.Trace("Plugin Finished Executing"); } } protected Entity CombineEntities(Entity preImageEntity, Entity entity) { if (preImageEntity != null) { var entityRtn = preImageEntity; foreach (var att in entity.Attributes) { if (entityRtn.Attributes.Contains(att.Key)) { entityRtn.Attributes.Remove(att.Key); // Remove Old value from Image } entityRtn.Attributes.Add(att); // add new Value from entity } return entityRtn; } return entity; //No preimage to merge so just return the entity. } } }
Thursday, January 23, 2014 12:46 AM