public static string ReplaceParameters(this IOrganizationService service, Entity target, string text) { if (string.IsNullOrWhiteSpace(text)) { return(""); } foreach (var param in RuntimeParameter.GetParametersFromString(text)) { if (!param.IsParentParameter()) { text = text.Replace(param.ParameterText, param.GetParameterValue(target)); } else { if (target.Contains(param.ParentLookupName)) { var parentRecord = service.Retrieve(target.GetAttributeValue <EntityReference>(param.ParentLookupName).LogicalName, target.GetAttributeValue <EntityReference>(param.ParentLookupName).Id, new ColumnSet(param.AttributeName)); text = text.Replace(param.ParameterText, param.GetParameterValue(parentRecord)); } else // target record has no parent, so use default value { text = text.Replace(param.ParameterText, param.DefaultValue); } } } return(text); }
public static RuntimeParameter Parse(string input) { var rp = new RuntimeParameter { ParameterText = input, AttributeName = input.Trim('{', '}') }; if (rp.AttributeName.Contains(':')) { string[] paramList = rp.AttributeName.Split(':'); rp.AttributeName = paramList[0]; if (rp.AttributeName == "rand") { rp.StringFormatter = paramList[1]; } else { if (paramList[1].Contains('?')) { rp.Conditional = ConditionalFormatter.Parse(paramList[1]); } else if (paramList.Length > 2) { rp.StringFormatter = paramList[1]; rp.Conditional = ConditionalFormatter.Parse(paramList[2]); } else { rp.StringFormatter = paramList[1]; } } } if (rp.AttributeName.Contains('|')) { rp.DefaultValue = rp.AttributeName.Split('|')[1]; rp.AttributeName = rp.AttributeName.Split('|')[0]; } if (rp.AttributeName.Contains('.')) { rp.ParentLookupName = rp.AttributeName.Split('.')[0]; rp.AttributeName = rp.AttributeName.Split('.')[1]; } return(rp); }
protected void Execute(LocalPluginContext context) { context.Trace("Getting Target entity"); var target = context.GetInputParameters <CreateInputParameters>().Target; context.Trace("Validate the Entity name"); context.Trace("Get Attribute List"); var attributeList = GetEntityMetadata(context, target.GetAttributeValue <string>("molyom_entityname")); context.Trace("Validate the Attribute name"); if (!attributeList.Select(a => a.LogicalName).Contains(target.GetAttributeValue <string>("molyom_attributename"))) { throw new InvalidPluginExecutionException("Specified Attribute does not exist."); } context.Trace("Validate the Trigger Attribute (if any)"); if (!string.IsNullOrEmpty(target.GetAttributeValue <string>("molyom_triggerattribute")) && !attributeList.Select(a => a.LogicalName).Contains(target.GetAttributeValue <string>("molyom_triggerattribute"))) { throw new InvalidPluginExecutionException("Specified Trigger Attribute does not exist."); } context.Trace("Validate the Attribute type"); if (attributeList.Single(a => a.LogicalName.Equals(target.GetAttributeValue <string>("molyom_attributename"))).AttributeType != AttributeTypeCode.String && attributeList.Single(a => a.LogicalName.Equals(target.GetAttributeValue <string>("molyom_attributename"))).AttributeType != AttributeTypeCode.Memo) { throw new InvalidPluginExecutionException("Attribute must be a text field."); } #region test parameters #if VALIDATEPARAMETERS var fields = new Dictionary <string, string>() { { "molyom_prefix", "Prefix" }, { "molyom_suffix", "Suffix" } }; foreach (var field in fields.Keys) { if (!target.Contains(field) || !target.GetAttributeValue <string>(field).Contains('{')) { continue; } if (target.GetAttributeValue <string>(field).Count(c => c.Equals('{')) != target.GetAttributeValue <string>(field).Count(c => c.Equals('}'))) { throw new InvalidPluginExecutionException($"Invalid parameter formatting in {fields[field]}"); } if (Regex.Matches(target.GetAttributeValue <string>(field), @"{(.*?)}").OfType <Match>().Select(m => m.Groups[0].Value).Distinct().Any(p => p.Substring(1).Contains('{'))) { throw new InvalidPluginExecutionException($"Invalid parameter formatting in {fields[field]}"); } try { foreach (var param in RuntimeParameter.GetParametersFromString(target.GetAttributeValue <string>(field))) { if (!param.IsParentParameter()) { if (!attributeList.Select(a => a.LogicalName).Contains(param.AttributeName)) { throw new InvalidPluginExecutionException($"{param.AttributeName} is not a valid attribute name in {fields[field]} value"); } } else { if (!attributeList.Select(a => a.LogicalName).Contains(param.ParentLookupName)) { throw new InvalidPluginExecutionException($"{param.ParentLookupName} is not a valid attribute name in {fields[field]} value"); } 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($"{param.ParentLookupName} must be a Lookup attribute type in {fields[field]} value"); } var parentLookupAttribute = (LookupAttributeMetadata)GetAttributeMetadata(context, target.GetAttributeValue <string>("molyom_entityname"), param.ParentLookupName); if (!parentLookupAttribute.Targets.Any(e => GetEntityMetadata(context, e).Select(a => a.LogicalName).Contains(param.AttributeName))) { throw new InvalidPluginExecutionException($"Invalid attribute on {param.ParentLookupName} parent entity, in {fields[field]} value"); } } } } catch (InvalidPluginExecutionException) { throw; } catch { throw new InvalidPluginExecutionException($"Failed to parse Runtime Parameters in {fields[field]} value."); } } #endif #endregion if (target.Contains("molyom_conditionaloptionset")) { context.Trace("Validate Conditional OptionSet"); if (!attributeList.Select(a => a.LogicalName).Contains(target.GetAttributeValue <string>("molyom_conditionaloptionset"))) { throw new InvalidPluginExecutionException("Specified Conditional OptionSet does not exist"); } if (attributeList.Single(a => a.LogicalName.Equals(target.GetAttributeValue <string>("molyom_conditionaloptionset"))).AttributeType != AttributeTypeCode.Picklist) { throw new InvalidPluginExecutionException("Conditional Attribute must be an OptionSet"); } context.Trace("Validate Conditional Value"); var optionSetMetadata = (PicklistAttributeMetadata)GetAttributeMetadata(context, target.GetAttributeValue <string>("molyom_entityname"), target.GetAttributeValue <string>("molyom_conditionaloptionset")); //attributeResponse.AttributeMetadata; if (!optionSetMetadata.OptionSet.Options.Select(o => o.Value).Contains(target.GetAttributeValue <int>("molyom_conditionalvalue"))) { throw new InvalidPluginExecutionException("Conditional Value does not exist in OptionSet"); } } #region Duplicate Check #if DUPLICATECHECK context.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("molyom_uniquecodegenerator") .Where(a => a.GetAttributeValue <string>("molyom_entityname").Equals(target.GetAttributeValue <string>("molyom_entityname")) && a.GetAttributeValue <string>("molyom_attributename").Equals(target.GetAttributeValue <string>("molyom_attributename"))) .Select(a => new { Id = a.GetAttributeValue <Guid>("molyom_uniquecodegeneratorid"), ConditionalOption = a.GetAttributeValue <string>("molyom_conditionaloptionset"), ConditionalValue = a.GetAttributeValue <int>("molyom_conditionalvalue") }) .ToList(); if (!target.Contains("molyom_conditionaloptionset") && autoNumberList.Any()) { throw new InvalidPluginExecutionException("Duplicate Code record exists."); } if (autoNumberList.Any(a => a.ConditionalOption.Equals(target.GetAttributeValue <string>("molyom_conditionaloptionset")) && a.ConditionalValue.Equals(target.GetAttributeValue <int>("molyom_conditionalvalue")))) { throw new InvalidPluginExecutionException("Duplicate Code record exists."); } #endif #endregion context.Trace("Insert the unique code generator Name attribute"); target["molyom_name"] = $"Unique Code for {target.GetAttributeValue<string>("molyom_entityname")}, {target.GetAttributeValue<string>("molyom_attributename")}"; }