protected void Execute(LocalPluginContext context) { #region Get the list of autonumber records applicable to the Target entity type var autoNumberIdList = context.OrganizationDataContext.CreateQuery("cel_autonumber") .Where(a => a.GetAttributeValue <string>("cel_entityname").Equals(context.PluginExecutionContext.PrimaryEntityName) && a.GetAttributeValue <OptionSetValue>("statecode").Value == 0) .OrderBy(a => a.GetAttributeValue <Guid>("cel_autonumberid")) // Insure they are ordered, to prevent deadlocks .Select(a => a.GetAttributeValue <Guid>("cel_autonumberid")); #endregion #region This loop locks the autonumber record(s) so only THIS transaction can read/write it foreach (Guid autoNumberId in autoNumberIdList) { Entity lockingUpdate = new Entity("cel_autonumber"); lockingUpdate.Id = autoNumberId; lockingUpdate["cel_preview"] = "555"; // Use the preview field as our "dummy" field - so we don't need a dedicated "dummy" context.OrganizationService.Update(lockingUpdate); } #endregion #region This loop populates the Target record, and updates the autonumber record(s) Entity Target = context.GetInputParameters <CreateInputParameters>().Target; foreach (Guid autoNumberId in autoNumberIdList) { Entity autoNumber = context.OrganizationService.Retrieve("cel_autonumber", autoNumberId, true); string targetAttribute = autoNumber.GetAttributeValue <string>("cel_attributename"); if ((autoNumber.Contains("cel_conditionaloptionset") && (!Target.Contains(autoNumber.GetAttributeValue <string>("cel_conditionaloptionset")) || Target.GetAttributeValue <OptionSetValue>(autoNumber.GetAttributeValue <string>("cel_conditionaloptionset")).Value != autoNumber.GetAttributeValue <int>("cel_conditionalvalue")))) { continue; // Continue, if this is a conditional optionset } //else if (autoNumber.Contains("cel_conditionallookup") && (!Target.Contains(autoNumber.GetAttributeValue<string>("cel_conditionallookup")) || Target.GetAttributeValue<EntityReference>(autoNumber.GetAttributeValue<string>("cel_conditionallookup")).Id != Guid.Parse(autoNumber.GetAttributeValue<string>("cel_conditionallookupvalue")))) //{ // continue; // Continue, if this is a conditional lookup //} else if (Target.Contains(targetAttribute) && !String.IsNullOrWhiteSpace(Target.GetAttributeValue <string>(targetAttribute))) { continue; // Continue, so we don't overwrite an existing value } // Generate number and insert into Target Record Target[targetAttribute] = String.Format("{0}{1}{2}", ReplaceParameters(autoNumber.GetAttributeValue <string>("cel_prefix"), Target, context.OrganizationService), autoNumber.GetAttributeValue <int>("cel_nextnumber").ToString("D" + autoNumber.GetAttributeValue <int>("cel_digits")), ReplaceParameters(autoNumber.GetAttributeValue <string>("cel_suffix"), Target, context.OrganizationService)); // Increment next number in db Entity updatedAutoNumber = new Entity("cel_autonumber"); updatedAutoNumber.Id = autoNumber.Id; updatedAutoNumber["cel_nextnumber"] = autoNumber.GetAttributeValue <int>("cel_nextnumber") + 1; updatedAutoNumber["cel_preview"] = Target[targetAttribute]; // fix the preview context.OrganizationService.Update(updatedAutoNumber); } #endregion }
protected void Execute(LocalPluginContext Context) { Trace("Get Target record"); Entity Target = Context.GetInputParameters <CreateInputParameters>().Target; string pluginName = String.Format(PLUGIN_NAME, Target.GetAttributeValue <string>("cel_entityname")); Trace("Check for existing plugin step"); if (Context.OrganizationDataContext.CreateQuery("sdkmessageprocessingstep").Where(s => s.GetAttributeValue <string>("name").Equals(pluginName)).ToList().Any()) { return; // Step already exists, nothing to do here. } Trace("Get the Id of this plugin"); Guid PluginTypeId = Context.OrganizationDataContext.CreateQuery("plugintype") .Where(s => s.GetAttributeValue <string>("name").Equals("Celedon.GetNextAutoNumber")) .Select(s => s.GetAttributeValue <Guid>("plugintypeid")) .First(); Trace("Get the 'Create' message id from this org"); Guid messageId = Context.OrganizationDataContext.CreateQuery("sdkmessage") .Where(s => s.GetAttributeValue <string>("name").Equals("Create")) .Select(s => s.GetAttributeValue <Guid>("sdkmessageid")) .First(); Trace("Get the filterId for 'Create' for the specific entity from this org"); Guid filterId = Context.OrganizationDataContext.CreateQuery("sdkmessagefilter") .Where(s => s.GetAttributeValue <string>("primaryobjecttypecode").Equals(Target.GetAttributeValue <string>("cel_entityname")) && s.GetAttributeValue <EntityReference>("sdkmessageid").Id.Equals(messageId)) .Select(s => s.GetAttributeValue <Guid>("sdkmessagefilterid")) .First(); Trace("Build new plugin step"); Entity newPluginStep = new Entity("sdkmessageprocessingstep") { Attributes = new AttributeCollection() { { "name", pluginName }, { "description", pluginName }, { "plugintypeid", PluginTypeId.ToEntityReference("plugintype") }, // This plugin { "sdkmessageid", messageId.ToEntityReference("sdkmessage") }, // Create Message { "configuration", Target.GetAttributeValue <string>("cel_entityname") }, // EntityName in the UnsecureConfig { "stage", PREOPERATION.ToOptionSetValue() }, // Execution Stage: Pre-Operation { "rank", 1 }, { "impersonatinguserid", Context.PluginExecutionContext.UserId.ToEntityReference("systemuser") }, // Run as SYSTEM user. Assumes we are currently running as the SYSTEM user { "sdkmessagefilterid", filterId.ToEntityReference("sdkmessagefilter") } } }; Trace("Create new plugin step"); Guid pluginStepId = Context.OrganizationService.Create(newPluginStep); }
protected void Execute(LocalPluginContext context) { Context = context; Trace("Getting Target entity"); Entity Target = Context.GetInputParameters <CreateInputParameters>().Target; Trace("Validate the Entity name"); Trace("Get Attribute List"); List <AttributeMetadata> attributeList = GetEntityMetadata(Target.GetAttributeValue <string>("cel_entityname")); Trace("Validate the Attribute name"); if (!attributeList.Select(a => a.LogicalName).Contains(Target.GetAttributeValue <string>("cel_attributename"))) { throw new InvalidPluginExecutionException("Specified Attribute does not exist."); } Trace("Validate the Attribute type"); if (attributeList.Single(a => a.LogicalName.Equals(Target.GetAttributeValue <string>("cel_attributename"))).AttributeType != AttributeTypeCode.String && attributeList.Single(a => a.LogicalName.Equals(Target.GetAttributeValue <string>("cel_attributename"))).AttributeType != AttributeTypeCode.Memo) { throw new InvalidPluginExecutionException("Attribute must be a text field."); } #region test parameters #if VALIDATEPARAMETERS Dictionary <string, string> fields = new Dictionary <string, string>() { { "cel_prefix", "Prefix" }, { "cel_suffix", "Suffix" } }; foreach (string field in fields.Keys) { if (Target.Contains(field) && Target.GetAttributeValue <string>(field).Contains('{')) { if (Target.GetAttributeValue <string>(field).Count(c => c.Equals('{')) != Target.GetAttributeValue <string>(field).Count(c => c.Equals('}'))) { throw new InvalidPluginExecutionException(String.Format("Invalid parameter formatting in {0}", fields[field])); } foreach (string p in Regex.Matches(Target.GetAttributeValue <string>(field), @"{(.*?)}").OfType <Match>().Select(m => m.Groups[0].Value).Distinct()) { if (p.Substring(1).Contains('{')) { throw new InvalidPluginExecutionException(String.Format("Invalid parameter formatting in {0}", fields[field])); } } try { foreach (RuntimeParameter param in RuntimeParameter.GetParametersFromString(Target.GetAttributeValue <string>(field))) { if (!param.IsParentParameter()) { if (!attributeList.Select(a => a.LogicalName).Contains(param.AttributeName)) { throw new InvalidPluginExecutionException(String.Format("{0} is not a valid attribute name in {1} value", param.AttributeName, fields[field])); } } else { if (!attributeList.Select(a => a.LogicalName).Contains(param.ParentLookupName)) { throw new InvalidPluginExecutionException(String.Format("{0} is not a valid attribute name in {1} value", param.ParentLookupName, fields[field])); } if (attributeList.Single(a => a.LogicalName.Equals(param.ParentLookupName)).AttributeType != AttributeTypeCode.Lookup && attributeList.Single(a => a.LogicalName.Equals(param.ParentLookupName)).AttributeType != AttributeTypeCode.Customer && attributeList.Single(a => a.LogicalName.Equals(param.ParentLookupName)).AttributeType != AttributeTypeCode.Owner) { throw new InvalidPluginExecutionException(String.Format("{0} must be a Lookup attribute type in {1} value", param.ParentLookupName, fields[field])); } var parentLookupAttribute = (LookupAttributeMetadata)GetAttributeMetadata(Target.GetAttributeValue <string>("cel_entityname"), param.ParentLookupName); if (!parentLookupAttribute.Targets.Any(e => GetEntityMetadata(e).Select(a => a.LogicalName).Contains(param.AttributeName))) { throw new InvalidPluginExecutionException(String.Format("invalid attribute on {0} parent entity, in {1} value", param.ParentLookupName, fields[field])); } } } } catch (InvalidPluginExecutionException) { throw; } catch { throw new InvalidPluginExecutionException(String.Format("Failed to parse Runtime Parameters in {0} value.", fields[field])); } } } #endif #endregion if (Target.Contains("cel_conditionaloptionset")) { Trace("Validate Conditional OptionSet"); if (!attributeList.Select(a => a.LogicalName).Contains(Target.GetAttributeValue <string>("cel_conditionaloptionset"))) { throw new InvalidPluginExecutionException("Specified Conditional OptionSet does not exist"); } if (attributeList.Single(a => a.LogicalName.Equals(Target.GetAttributeValue <string>("cel_conditionaloptionset"))).AttributeType != AttributeTypeCode.Picklist) { throw new InvalidPluginExecutionException("Conditional Attribute must be an OptionSet"); } Trace("Validate Conditional Value"); PicklistAttributeMetadata optionSetMetadata = (PicklistAttributeMetadata)GetAttributeMetadata(Target.GetAttributeValue <string>("cel_entityname"), Target.GetAttributeValue <string>("cel_conditionaloptionset")); //attributeResponse.AttributeMetadata; if (!optionSetMetadata.OptionSet.Options.Select(o => o.Value).Contains(Target.GetAttributeValue <int>("cel_conditionalvalue"))) { throw new InvalidPluginExecutionException("Conditional Value does not exist in OptionSet"); } } #region Duplicate Check #if DUPLICATECHECK Trace("Validate there are no duplicates"); // TODO: Fix this. duplicate detection works when all fields contain data, but fails when some fields are empty var autoNumberList = Context.OrganizationDataContext.CreateQuery("cel_autonumber") .Where(a => a.GetAttributeValue <string>("cel_entityname").Equals(Target.GetAttributeValue <string>("cel_entityname")) && a.GetAttributeValue <string>("cel_attributename").Equals(Target.GetAttributeValue <string>("cel_attributename"))) .Select(a => new { Id = a.GetAttributeValue <Guid>("cel_autonumberid"), ConditionalOption = a.GetAttributeValue <string>("cel_conditionaloptionset"), ConditionalValue = a.GetAttributeValue <int>("cel_conditionalvalue") }) .ToList(); if (!Target.Contains("cel_conditionaloptionset") && autoNumberList.Any()) { throw new InvalidPluginExecutionException("Duplicate AutoNumber record exists."); } else if (autoNumberList.Where(a => a.ConditionalOption.Equals(Target.GetAttributeValue <string>("cel_conditionaloptionset")) && a.ConditionalValue.Equals(Target.GetAttributeValue <int>("cel_conditionalvalue"))).Any()) { throw new InvalidPluginExecutionException("Duplicate AutoNumber record exists."); } #endif #endregion Trace("Insert the autoNumber Name attribute"); Target["cel_name"] = String.Format("AutoNumber for {0}, {1}", Target.GetAttributeValue <string>("cel_entityname"), Target.GetAttributeValue <string>("cel_attributename")); }
protected void Execute(LocalPluginContext context) { context.Trace("Get Target record"); var target = context.GetInputParameters <CreateInputParameters>().Target; var pluginName = string.Format(PluginName, target.GetAttributeValue <string>("cel_entityname")); if (target.GetAttributeValue <OptionSetValue>("cel_triggerevent").Value == 1) { pluginName += " Update"; } context.Trace("Check for existing plugin step"); if (context.OrganizationDataContext.CreateQuery("sdkmessageprocessingstep").Where(s => s.GetAttributeValue <string>("name").Equals(pluginName)).ToList().Any()) { return; // Step already exists, nothing to do here. } context.Trace("Build the configuration"); var config = new AutoNumberPluginConfig() { EntityName = target.GetAttributeValue <string>("cel_entityname"), EventName = target.GetAttributeValue <OptionSetValue>("cel_triggerevent").Value == 1 ? "Update" : "Create" }; context.Trace("Get the Id of this plugin"); var pluginTypeId = context.OrganizationDataContext.CreateQuery("plugintype") .Where(s => s.GetAttributeValue <string>("name").Equals(typeof(GetNextAutoNumber).FullName)) .Select(s => s.GetAttributeValue <Guid>("plugintypeid")) .First(); context.Trace("Get the message id from this org"); var messageId = context.OrganizationDataContext.CreateQuery("sdkmessage") .Where(s => s.GetAttributeValue <string>("name").Equals(config.EventName)) .Select(s => s.GetAttributeValue <Guid>("sdkmessageid")) .First(); context.Trace("Get the filterId for for the specific entity from this org"); var filterId = context.OrganizationDataContext.CreateQuery("sdkmessagefilter") .Where(s => s.GetAttributeValue <string>("primaryobjecttypecode").Equals(config.EntityName) && s.GetAttributeValue <EntityReference>("sdkmessageid").Id.Equals(messageId)) .Select(s => s.GetAttributeValue <Guid>("sdkmessagefilterid")) .First(); context.Trace("Build new plugin step"); var newPluginStep = new Entity("sdkmessageprocessingstep") { Attributes = new AttributeCollection() { { "name", pluginName }, { "description", pluginName }, { "plugintypeid", pluginTypeId.ToEntityReference("plugintype") }, // This plugin type { "sdkmessageid", messageId.ToEntityReference("sdkmessage") }, // Create or Update Message { "configuration", config.ToJson() }, // EntityName and RegisteredEvent in the UnsecureConfig { "stage", PipelineStage.PreOperation.ToOptionSetValue() }, // Execution Stage: Pre-Operation { "rank", 1 }, { "impersonatinguserid", context.PluginExecutionContext.UserId.ToEntityReference("systemuser") }, // Run as SYSTEM user. Assumes we are currently running as the SYSTEM user { "sdkmessagefilterid", filterId.ToEntityReference("sdkmessagefilter") }, } }; context.Trace("Create new plugin step"); var sdkmessageprocessingstepid = context.OrganizationService.Create(newPluginStep); // only add the image if the type is update, on create a value cannot be overridden if (target.GetAttributeValue <OptionSetValue>("cel_triggerevent").Value == 1) { context.Trace("Build new plugin step image"); var newPluginStepImage = new Entity("sdkmessageprocessingstepimage") { Attributes = new AttributeCollection() { { "sdkmessageprocessingstepid", sdkmessageprocessingstepid.ToEntityReference("sdkmessageprocessingstep") }, { "imagetype", 0.ToOptionSetValue() }, // PreImage { "messagepropertyname", "Target" }, { "name", "Image" }, { "entityalias", "Image" }, { "attributes", target.GetAttributeValue <string>("cel_attributename") }, //Only incluce the one attribute we really need. } }; context.Trace("Create new plugin step image"); context.OrganizationService.Create(newPluginStepImage); } }