I have a plugin that creates records in an entity called "Alter Unit Order". It is supposed to create records for each day from contract start date to contract end date. No matter what, the plugin will only create 33 records. I'm thinking its probably because of how many FetchXML queries are being made. If so, what is the fix?
Here the code for the plugin:
using System;
using System.ServiceModel;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Query;
using Plugins;
/// <summary>
/// This plugin takes the data provided in the contract lines and makes Unit Orders..
/// Inside the unit orders, an Alter Unit Orders table is present.
/// The Alter Unit Orders table describes the daily order for each day in the contract's duration.
/// </summary>
namespace DCWIMS.Plugins
{
[CrmPluginRegistration(MessageNameEnum.Update,
"contract",
StageEnum.PostOperation,
ExecutionModeEnum.Asynchronous,
"statecode",
"Post-Update Contract",
1000,
IsolationModeEnum.Sandbox,
Image1Name = "PreImage",
Image1Type = ImageTypeEnum.PreImage,
Image1Attributes = "")]
public class UnitPlugin : IPlugin
{
public void Execute(IServiceProvider serviceProvider)
{
// Extract the tracing service for use in debugging sandboxed plug-ins.
// Will be registering this plugin, thus will need to add tracing service related code.
ITracingService tracing = (ITracingService)serviceProvider.GetService(typeof(ITracingService));
//obtain execution context from service provider.
IPluginExecutionContext context = (IPluginExecutionContext)
serviceProvider.GetService(typeof(IPluginExecutionContext));
// The InputParameters collection contains all the data passed in the message request.
if (context.InputParameters.Contains("Target") &&
context.InputParameters["Target"] is Entity)
{
//obtain the target entity from the input parameters.
Entity entity = (Entity)context.InputParameters["Target"];
//Get the before image of the updated contract
Entity PreImage = context.PreEntityImages["PreImage"];
//verify that the target entity represents the the contract entity and contract is Active (statecode 2)
if (entity.LogicalName != "contract" || entity.GetAttributeValue<OptionSetValue>("statecode").Value != 2)
return;
//Redundancy to prevent execution when going from Hold/cancel to active
if (PreImage.GetAttributeValue<OptionSetValue>("statecode").Value == 3 || entity.Contains("cancelon"))
return;
//obtain the organization service for web service calls.
IOrganizationServiceFactory serviceFactory =
(IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
//This will be used as service for web service calls
IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);
//Core Plugin Code in try block
try
{
//Get Contract StartDate
DateTime startDate = (DateTime)PreImage["activeon"];
//Get Contract EndDate
DateTime endDate = (DateTime)PreImage["expireson"];
//Create an instance of the range class
Eachday range = new Eachday();
//use Weekday method of range class to get a weekdays list
var weekdays = range.WeekDay(startDate, endDate);
//Get Contract Number
string contractNumber = (string)PreImage["contractnumber"];
//Get Unit Order Lookup Id
EntityReference unitOrder = (EntityReference)PreImage.Attributes["new_unitorderid"];
var unitOrderId = unitOrder.Id;
//Query for the different Location Destinations and Serving Groups
string fetch = @" <fetch version='1.0' output-format='xml-platform' mapping='logical' distinct='true'>
<entity name='contractdetail'>
<attribute name='new_servinggroup' alias='serving' />
<attribute name='new_locationdestination' />
<filter type='and'>
<condition attribute='new_locationdestination' operator='not-null' />
</filter>
<link-entity name='contract' from='contractid' to='contractid' alias='ad'>
<filter type='and'>
<condition attribute='contractnumber' operator='eq' value='" + contractNumber + @"' />
</filter>
</link-entity>
</entity>
</fetch>";
//Put fetch result into an entity collection
EntityCollection result =
service.RetrieveMultiple(new FetchExpression(fetch));
//iterate through entire contract duration and create the records
foreach (var day in weekdays)
{
var currentday = day.Split(',')[0];
//Create a record for each Serving Group and Destination pair
foreach (var ent in result.Entities)
{
//Get the Serving Group
AliasedValue aliasedValue = ent.GetAttributeValue<AliasedValue>("serving");
object aliasValue = aliasedValue.Value;
OptionSetValue optionset = (OptionSetValue)aliasValue;
int group = optionset.Value;
//Get the location destination
var location = ent.GetAttributeValue<string>("new_locationdestination");
//Create the record and fill the attributes
Entity alterunit = new Entity("new_alterunitorder");
alterunit.Attributes.Add("new_orderdate", DateTime.Parse(day));
alterunit.Attributes.Add("new_name", contractNumber);
alterunit.Attributes["new_orderlineid"] =
new EntityReference("new_units", unitOrderId);
var selection = new OptionSetValue(group);
alterunit.Attributes["new_servinggroup"] = selection;
alterunit.Attributes.Add("new_location", location);
//use Fetch Query here and feed the switch below
//Fetch AM SUM for the current serving group and location
string fetch_am = @" <fetch aggregate = 'true' distinct = 'false' >
<entity name = 'contractdetail' >
<attribute name = 'new_mondayunits' alias = 'new_mondayunits_sum' aggregate = 'sum' />
<attribute name = 'new_tuesdayunits' alias = 'new_tuesdayunits_sum' aggregate = 'sum' />
<attribute name = 'new_unitswednesday' alias = 'new_unitswednesday_sum' aggregate = 'sum' />
<attribute name = 'new_unitsthursday' alias = 'new_unitsthursday_sum' aggregate = 'sum' />
<attribute name = 'new_unitsfriday' alias = 'new_unitsfriday_sum' aggregate = 'sum' />
<filter type='and' >
<condition value= '100000001' attribute = 'new_servingtime' operator = 'eq' />
<condition value = '" + group + @"' attribute = 'new_servinggroup' operator= 'eq' />
<condition value = '" + location + @"' attribute = 'new_locationdestination' operator= 'eq' />
<condition value = '0' attribute = 'statecode' operator= 'eq' />
</filter >
<link-entity name = 'contract' from = 'contractid' to = 'contractid' alias = 'aa'>
<filter type = 'and' >
<condition attribute = 'contractnumber' operator= 'eq' value = '" + contractNumber + @"' />
</filter >
</link-entity >
</entity >
</fetch > ";
var fetch_one = new FetchQuery(fetch_am);
var am_list = fetch_one.Result(serviceProvider);
//Fetch LUNCH SUM for the current serving group and location
string fetch_lunch = @" <fetch aggregate = 'true' distinct = 'false' >
<entity name = 'contractdetail' >
<attribute name = 'new_mondayunits' alias = 'new_mondayunits_sum' aggregate = 'sum' />
<attribute name = 'new_tuesdayunits' alias = 'new_tuesdayunits_sum' aggregate = 'sum' />
<attribute name = 'new_unitswednesday' alias = 'new_unitswednesday_sum' aggregate = 'sum' />
<attribute name = 'new_unitsthursday' alias = 'new_unitsthursday_sum' aggregate = 'sum' />
<attribute name = 'new_unitsfriday' alias = 'new_unitsfriday_sum' aggregate = 'sum' />
<filter type='and' >
<condition value= '100000002' attribute = 'new_servingtime' operator = 'eq' />
<condition value = '" + group + @"' attribute = 'new_servinggroup' operator= 'eq' />
<condition value = '" + location + @"' attribute = 'new_locationdestination' operator= 'eq' />
<condition value = '0' attribute = 'statecode' operator= 'eq' />
</filter >
<link-entity name = 'contract' from = 'contractid' to = 'contractid' alias = 'aa'>
<filter type = 'and' >
<condition attribute = 'contractnumber' operator= 'eq' value = '" + contractNumber + @"' />
</filter >
</link-entity >
</entity >
</fetch >";
var fetch_two = new FetchQuery(fetch_lunch);
var lunch_list = fetch_two.Result(serviceProvider);
//Fetch PM SUM for the current Serving Group and location
string fetch_pm = @" <fetch aggregate = 'true' distinct = 'false' >
<entity name = 'contractdetail' >
<attribute name = 'new_mondayunits' alias = 'new_mondayunits_sum' aggregate = 'sum' />
<attribute name = 'new_tuesdayunits' alias = 'new_tuesdayunits_sum' aggregate = 'sum' />
<attribute name = 'new_unitswednesday' alias = 'new_unitswednesday_sum' aggregate = 'sum' />
<attribute name = 'new_unitsthursday' alias = 'new_unitsthursday_sum' aggregate = 'sum' />
<attribute name = 'new_unitsfriday' alias = 'new_unitsfriday_sum' aggregate = 'sum' />
<filter type='and' >
<condition value= '100000003' attribute = 'new_servingtime' operator = 'eq' />
<condition value = '" + group + @"' attribute = 'new_servinggroup' operator= 'eq' />
<condition value = '" + location + @"' attribute = 'new_locationdestination' operator= 'eq' />
<condition value = '0' attribute = 'statecode' operator= 'eq' />
</filter >
<link-entity name = 'contract' from = 'contractid' to = 'contractid' alias = 'aa'>
<filter type = 'and' >
<condition attribute = 'contractnumber' operator= 'eq' value = '" + contractNumber + @"' />
</filter >
</link-entity >
</entity >
</fetch >";
var fetch_three = new FetchQuery(fetch_pm);
var pm_list = fetch_three.Result(serviceProvider);
switch (currentday)
{
case "Monday":
alterunit.Attributes.Add("new_amsnack", am_list[0]);
alterunit.Attributes.Add("new_lunch", lunch_list[0]);
alterunit.Attributes.Add("new_pmsnack", pm_list[0]);
break;
case "Tuesday":
alterunit.Attributes.Add("new_amsnack", am_list[1]);
alterunit.Attributes.Add("new_lunch", lunch_list[1]);
alterunit.Attributes.Add("new_pmsnack", pm_list[1]);
break;
case "Wednesday":
alterunit.Attributes.Add("new_amsnack", am_list[2]);
alterunit.Attributes.Add("new_lunch", lunch_list[2]);
alterunit.Attributes.Add("new_pmsnack", pm_list[2]);
break;
case "Thursday":
alterunit.Attributes.Add("new_amsnack", am_list[3]);
alterunit.Attributes.Add("new_lunch", lunch_list[3]);
alterunit.Attributes.Add("new_pmsnack", pm_list[3]);
break;
case "Friday":
alterunit.Attributes.Add("new_amsnack", am_list[4]);
alterunit.Attributes.Add("new_lunch", lunch_list[4]);
alterunit.Attributes.Add("new_pmsnack", pm_list[4]);
break;
default:
Console.WriteLine($"An unexpected value ({currentday})");
break;
}
service.Create(alterunit);
}
}
}
catch (FaultException<OrganizationServiceFault> ex)
{
throw new InvalidPluginExecutionException("An error occured.. Phil is responsible.", ex);
}
catch (Exception ex)
{
tracing.Trace("An Error Occured: {0}", ex.ToString());
throw;
}
}
}
}
}