public static string ToCommaSeparatedString(this Microsoft.Xrm.Sdk.EntityCollection value)
        {
            if (value == null)
            {
                return("None");
            }

            string output = string.Empty;

            foreach (Microsoft.Xrm.Sdk.Entity record in value.Entities)
            {
                if (record.Contains("partyid"))
                {
                    if (!(output.Equals(String.Empty)))
                    {
                        output += ", ";
                    }

                    Microsoft.Xrm.Sdk.EntityReference entRef = (Microsoft.Xrm.Sdk.EntityReference)record.Attributes["partyid"];
                    output += entRef.Name + "";
                }
                else if (record.Contains("addressused"))
                {
                    string emailAddress = (string)record["addressused"];
                    if (!(emailAddress.Equals(String.Empty)))
                    {
                        if (!(output.Equals(String.Empty)))
                        {
                            output += ", ";
                        }
                        output += emailAddress;
                    }
                }
                else if (record.Contains("name"))
                {
                    string name = (string)record["name"];
                    if (!(name.Equals(String.Empty)))
                    {
                        if (!(output.Equals(String.Empty)))
                        {
                            output += ", ";
                        }
                        output += name;
                    }
                }
                else if (record.Contains("crmcs_name"))
                {
                    string name = (string)record["crmcs_name"];
                    if (!(name.Equals(String.Empty)))
                    {
                        if (!(output.Equals(String.Empty)))
                        {
                            output += ", ";
                        }
                        output += name;
                    }
                }
            }
            return(output);
        }
Ejemplo n.º 2
0
        public Guid?CreateTaskToCRMIncident(string ticketnumber, TimeItem timeItem)
        {
            try
            {
                Microsoft.Xrm.Sdk.Query.QueryExpression GetCasesByTicketNumber = new Microsoft.Xrm.Sdk.Query.QueryExpression {
                    EntityName = "incident", ColumnSet = new Microsoft.Xrm.Sdk.Query.ColumnSet(true)
                };
                GetCasesByTicketNumber.Criteria.AddCondition("ticketnumber", Microsoft.Xrm.Sdk.Query.ConditionOperator.Equal, ticketnumber);
                Microsoft.Xrm.Sdk.EntityCollection CaseResults = _service.RetrieveMultiple(GetCasesByTicketNumber);

                if (CaseResults.Entities.Count < 1)
                {
                    return(null);
                }

                Microsoft.Xrm.Sdk.Entity followup = new Microsoft.Xrm.Sdk.Entity("task");

                if (timeItem.title != null)
                {
                    followup["subject"] = timeItem.title.Replace(ticketnumber, "");
                }

                if (timeItem.description != null)
                {
                    followup["description"] = timeItem.description;
                }

                if (timeItem.isBillable == true && timeItem.isBillable != null)
                {
                    followup["actualdurationminutes"]    = (int)TimeSpan.Parse(timeItem.time).TotalMinutes;
                    followup["hsal_nonbillableduration"] = 0;
                }
                else
                {
                    followup["actualdurationminutes"]    = 0;
                    followup["hsal_nonbillableduration"] = (int)TimeSpan.Parse(timeItem.time).TotalMinutes;
                }

                followup["actualstart"] = DateTime.UtcNow;

                followup["regardingobjectid"] = CaseResults.Entities[0].ToEntityReference();

                Guid taskId = _service.Create(followup);

                Microsoft.Crm.Sdk.Messages.SetStateRequest req = new Microsoft.Crm.Sdk.Messages.SetStateRequest();
                req.EntityMoniker = new Microsoft.Xrm.Sdk.EntityReference("task", taskId);
                req.State         = new Microsoft.Xrm.Sdk.OptionSetValue(1);
                req.Status        = new Microsoft.Xrm.Sdk.OptionSetValue((5));
                _service.Execute(req);

                return(taskId);
            }
            catch (Exception ex)
            {
                //log error
                throw ex;
            }
        }
Ejemplo n.º 3
0
        public Guid?CreateExternalComment(string ticketnumber, TimeItem timeItem)
        {
            try
            {
                Microsoft.Xrm.Sdk.Query.QueryExpression GetCasesByTicketNumber = new Microsoft.Xrm.Sdk.Query.QueryExpression {
                    EntityName = "incident", ColumnSet = new Microsoft.Xrm.Sdk.Query.ColumnSet(true)
                };
                GetCasesByTicketNumber.Criteria.AddCondition("ticketnumber", Microsoft.Xrm.Sdk.Query.ConditionOperator.Equal, ticketnumber);
                Microsoft.Xrm.Sdk.EntityCollection CaseResults = _service.RetrieveMultiple(GetCasesByTicketNumber);

                if (CaseResults.Entities.Count < 1)
                {
                    return(null);
                }

                Microsoft.Xrm.Sdk.Entity comment = new Microsoft.Xrm.Sdk.Entity("hsal_externalcomments");

                if (timeItem.title != null)
                {
                    comment["subject"] = timeItem.title.Replace(ticketnumber, "");
                }

                if (timeItem.description != null)
                {
                    comment["description"] = timeItem.description;
                }

                comment["regardingobjectid"] = CaseResults.Entities[0].ToEntityReference();

                Guid externalCommentId = _service.Create(comment);

                Microsoft.Crm.Sdk.Messages.SetStateRequest req = new Microsoft.Crm.Sdk.Messages.SetStateRequest();
                req.EntityMoniker = new Microsoft.Xrm.Sdk.EntityReference("hsal_externalcomments", externalCommentId);
                req.State         = new Microsoft.Xrm.Sdk.OptionSetValue(1);
                req.Status        = new Microsoft.Xrm.Sdk.OptionSetValue((2));
                _service.Execute(req);

                return(externalCommentId);
            }
            catch (Exception ex)
            {
                //log error
                throw ex;
            }
        }
Ejemplo n.º 4
0
        public void Execute(IServiceProvider serviceProvider)
        {
            var context        = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
            var serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));

            var toolOrgService = serviceFactory.CreateOrganizationService(null);

            var tracingService = (ITracingService)serviceProvider.GetService(typeof(ITracingService));
            var userId         = context.UserId;
            var message        = context.MessageName;
            var stage          = context.Stage;
            var isAsync        = context.Mode == 1;

            var type = message.Contains("_") ? CrmEventType.CustomPlugin : (CrmEventType)Enum.Parse(typeof(CrmEventType), context.MessageName);

            IPluginContext pluginContext = new Services.PluginContext(this.UnsecureConfig, this.SecureConfig, context, type, userId);

            using (var serviceCache = new Reflection.ServiceCache(context, serviceFactory, tracingService, pluginContext, this.UnsecureConfig, this.SecureConfig))
            {
                var entityName = context.PrimaryEntityName;

                if (entityName == "none" || Reflection.Types.MESSAGE_WITHOUT_PRIMARY_ENTITY.Contains(message))
                {
                    entityName = null;
                }

                var methods = PluginMethodCache.ForPlugin(this.GetType(), stage, message, entityName, context.Mode == 1);

                var logs = new System.Collections.Generic.List <string>();
                try
                {
                    foreach (var method in methods)
                    {
                        #region evaluate if needed - based on If attributes
                        if (method.IfAttribute != null)
                        {
                            var con = Reflection.MethodConditionEvaluater.Evaluate(method.IfAttribute, context);
                            if (!con)
                            {
                                continue;
                            }
                        }
                        #endregion

                        var nextlog = $"{method.Name}(";
                        #region find out if method is relevant, looking a target fields
                        if (message == Attributes.StepAttribute.MessageEnum.Update.ToString() && !method.FilterAllProperties)
                        {
                            var targetEntity = (Microsoft.Xrm.Sdk.Entity)context.InputParameters["Target"];
                            if (!method.IsRelevant(targetEntity))
                            {
                                continue;
                            }
                        }
                        #endregion

                        #region now resolve all parameters
                        var args = new object[method.Parameters.Length];
                        var ix   = 0;
                        System.ComponentModel.INotifyPropertyChanged mergedimage = null;
                        System.ComponentModel.INotifyPropertyChanged target      = null;
                        var comma = "";
                        foreach (var p in method.Parameters)
                        {
                            nextlog += $"{comma}{p?.FromType?.FullName}";
                            comma    = ", ";
                            if (p.IsInputParameter)
                            {
                                if (context.InputParameters.ContainsKey(p.Name))
                                {
                                    args[ix] = context.InputParameters[p.Name];
                                }
                                else
                                {
                                    if (p.Name != null)
                                    {
                                        if (p.Name.ToLower() == nameof(this.UnsecureConfig).ToLower())
                                        {
                                            args[ix] = this.UnsecureConfig;
                                        }
                                        else
                                        if (p.Name.ToLower() == nameof(this.SecureConfig).ToLower())
                                        {
                                            args[ix] = this.SecureConfig;
                                        }
                                        else
                                        {
                                            args[ix] = null;
                                        }
                                    }
                                    else
                                    {
                                        args[ix] = null;
                                    }
                                }
                            }
                            else
                            {
                                args[ix] = serviceCache.Resolve(p, toolOrgService);
                            }

                            #region set TargetAttributes
                            if (message == "Create" || message == "Update")
                            {
                                if (p.IsMergedimage || p.IsPreimage || p.IsPostimage)
                                {
                                    var tap = args[ix].GetType().GetProperty("TargetAttributes");

                                    if (tap != null)
                                    {
                                        var tg = (Microsoft.Xrm.Sdk.Entity)context.InputParameters["Target"];
                                        tap.SetValue(args[ix], tg.Attributes);
                                    }
                                }
                            }
                            #endregion

                            #region set preimage attributes
                            if (p.IsMergedimage || p.IsTarget || p.IsPreimage || p.IsPostimage)
                            {
                                if (message == "Update" || message == "Delete")
                                {
                                    if (context.PreEntityImages != null && context.PreEntityImages.Values != null)
                                    {
                                        var col = new AttributeCollection();
                                        foreach (Entity pre in context.PreEntityImages.Values)
                                        {
                                            foreach (var at in pre.Attributes)
                                            {
                                                if (!col.Keys.Contains(at.Key))
                                                {
                                                    col.Add(at.Key, at.Value);
                                                }
                                            }
                                        }
                                        var tap = args[ix].GetType().GetProperty("PreimageAttributes");

                                        if (tap != null)
                                        {
                                            tap.SetValue(args[ix], col);
                                        }
                                    }
                                }
                            }
                            #endregion

                            #region add property notification to ensure mirror of set in pre state on merged images
                            if (stage <= 20 && message == "Update")
                            {
                                if (p.IsMergedimage)
                                {
                                    mergedimage = (System.ComponentModel.INotifyPropertyChanged)args[ix];
                                }

                                if (p.IsTarget)
                                {
                                    target = args[ix] as System.ComponentModel.INotifyPropertyChanged;
                                }
                            }
                            #endregion
                            ix++;
                        }
                        #endregion

                        #region add mergedimage eventlistener if applicable
                        PropertyMirror mergedimageMirror = null;
                        PropertyMirror targetMirror      = null;

                        if (stage <= 20 && message == "Update")
                        {
                            if (mergedimage != null)
                            {
                                var tg = (Microsoft.Xrm.Sdk.Entity)context.InputParameters["Target"];
                                mergedimageMirror            = new PropertyMirror(tg);
                                mergedimage.PropertyChanged += mergedimageMirror.MirrorpropertyChanged;
                            }

                            if (mergedimage != null && target != null)
                            {
                                targetMirror            = new PropertyMirror((Microsoft.Xrm.Sdk.Entity)mergedimage);
                                target.PropertyChanged += targetMirror.MirrorpropertyChanged;
                            }
                        }
                        #endregion

                        #region run the method
                        var inError = false;
                        nextlog += ")";
                        try
                        {
                            logs.Add($"before: {nextlog}");
                            var result = method.Invoke(this, args);
                            logs.Add($"after: {nextlog}");

                            if (result != null && method.OutputProperties != null && method.OutputProperties.Count > 0)
                            {
                                foreach (var key in method.OutputProperties.Keys)
                                {
                                    var output = method.OutputProperties[key];
                                    var value  = key.GetValue(result);
                                    if (value != null)
                                    {
                                        #region map strongly typed entities back to base entities to allow correct serrialization back to client
                                        if (value is Microsoft.Xrm.Sdk.Entity e && value.GetType() != typeof(Microsoft.Xrm.Sdk.Entity))
                                        {
                                            var entity = new Microsoft.Xrm.Sdk.Entity(e.LogicalName, e.Id);
                                            entity.Attributes = e.Attributes;
                                            value             = entity;
                                        }

                                        if (value is Microsoft.Xrm.Sdk.EntityCollection ec && ec.Entities != null && ec.Entities.Count > 0)
                                        {
                                            var final = new Microsoft.Xrm.Sdk.EntityCollection {
                                                EntityName = ec.EntityName
                                            };
                                            foreach (var ent in ec.Entities)
                                            {
                                                if (ent.GetType() == typeof(Microsoft.Xrm.Sdk.Entity))
                                                {
                                                    final.Entities.Add(ent);
                                                }
                                                else
                                                {
                                                    var entity = new Microsoft.Xrm.Sdk.Entity(ent.LogicalName, ent.Id);
                                                    entity.Attributes = ent.Attributes;
                                                    final.Entities.Add(entity);
                                                }
                                            }
                                            value = final;
                                        }
                                        #endregion

                                        context.OutputParameters[output.LogicalName] = value;
                                    }
                                }
                            }
                        }
                        catch (Microsoft.Xrm.Sdk.InvalidPluginExecutionException)
                        {
                            inError = true;
                            throw;
                        }
                        catch (System.Reflection.TargetInvocationException te)
                        {
                            inError = true;
                            if (te.InnerException != null && te.InnerException is Microsoft.Xrm.Sdk.InvalidPluginExecutionException)
                            {
                                throw te.InnerException;
                            }

                            if (te.InnerException != null)
                            {
                                throw new InvalidPluginExecutionException(te.InnerException.Message, te.InnerException);
                            }

                            throw new InvalidPluginExecutionException(te.Message, te);
                        }
                        catch (Exception be)
                        {
                            inError = true;
                            if (be.GetType().BaseType?.FullName == "Kipon.Xrm.Exceptions.BaseException")
                            {
                                // it is not a unit test, its the real thing, so we map the exception to a supported exception to allow message to parse all the way to the client
                                throw new InvalidPluginExecutionException($"{be.GetType().FullName}: {be.Message}", be);
                            }

                            throw new InvalidPluginExecutionException(be.Message, be);
                        }
                        finally
                        {
                            if (!inError)
                            {
                                #region cleanup mirror
                                if (stage <= 20)
                                {
                                    if (mergedimageMirror != null)
                                    {
                                        mergedimage.PropertyChanged -= mergedimageMirror.MirrorpropertyChanged;
                                        mergedimageMirror            = null;
                                    }

                                    if (targetMirror != null)
                                    {
                                        target.PropertyChanged -= targetMirror.MirrorpropertyChanged;
                                        targetMirror            = null;
                                    }
                                }
                                #endregion

                                #region prepare for next method
                                serviceCache.OnStepFinalize();
                                #endregion
                            }
                        }
                        #endregion
                    }
                } catch (Exception ex)
                {
                    tracingService.Trace(ex.Message);
                    tracingService.Trace(ex.GetType().FullName);
                    tracingService.Trace(ex.StackTrace);
                    foreach (var l in logs)
                    {
                        tracingService.Trace(l);
                    }
                    throw;
                }
            }
        }
Ejemplo n.º 5
0
 /// <summary>internal</summary>
 public QuickFindResult(int error, EntityCollection entities)
 {
     this.errorCode      = error;
     this.data           = entities;
     this.queryColumnSet = (DataCollection <string>)null;
 }
        private static string MapAttributesToJsonTemplate(Microsoft.Xrm.Sdk.Entity record, string jsonTemplate, string orgUrl, bool doHyperlinks = true, bool doLinksAsAdaptive = true)
        {
            try
            {
                if (!string.IsNullOrEmpty(jsonTemplate))
                {
                    foreach (KeyValuePair <string, object> kvp in record.Attributes)
                    {
                        if (!jsonTemplate.Contains("{" + kvp.Key + "}"))
                        {
                            // move to next element if not detected within the template
                            continue;
                        }

                        string type      = kvp.Value.GetType().Name.ToLower();
                        string value     = kvp.Value.ToString();
                        string hyperlink = string.Empty;

                        switch (type)
                        {
                        case ("entityreference"):
                        {
                            Microsoft.Xrm.Sdk.EntityReference refVal = (Microsoft.Xrm.Sdk.EntityReference)kvp.Value;
                            value = refVal.Name;
                            if (doHyperlinks)
                            {
                                hyperlink = orgUrl + "/main.aspx?forceUCI=1&etn=" + refVal.LogicalName + "&id=" + refVal.Id + "&pagetype=entityrecord";
                            }
                            break;
                        }

                        case ("optionsetvalue"):
                        {
                            value = record.GetValueDisplayString(kvp.Key);
                            break;
                        }

                        case ("datetime"):
                        {
                            DateTime dtVal = (DateTime)kvp.Value;
                            value = dtVal.ToString("dd/MM/yyyy");
                            break;
                        }

                        case ("money"):
                        {
                            Money mVal = (Money)kvp.Value;
                            value = mVal.Value.ToString("#,###,##0");
                            break;
                        }

                        case ("entitycollection"):
                        {
                            if (kvp.Value != null)
                            {
                                Microsoft.Xrm.Sdk.EntityCollection collection = (Microsoft.Xrm.Sdk.EntityCollection)kvp.Value;
                                value = collection.ToCommaSeparatedString();
                            }
                            else
                            {
                                value = "None";
                            }
                            break;
                        }

                        default:
                        {
                            object o = kvp.Value;
                            if (o != null)
                            {
                                value = o.ToString();
                            }
                            else
                            {
                                value = "";
                            }
                            break;
                        }
                        }

                        if (!String.IsNullOrEmpty(hyperlink))
                        {
                            if (doLinksAsAdaptive)
                            {
                                // In AdaptiveCards, Links are formatted as [caption](url link)
                                jsonTemplate = jsonTemplate.Replace("{" + kvp.Key.ToLower() + "}", "[" + value + "](" + hyperlink + ")");
                            }
                            else
                            {
                                jsonTemplate = jsonTemplate.Replace("{" + kvp.Key.ToLower() + "}", hyperlink);
                            }
                        }
                        else
                        {
                            jsonTemplate = jsonTemplate.Replace("{" + kvp.Key.ToLower() + "}", value);
                        }
                        if (orgUrl != null)
                        {
                            jsonTemplate = jsonTemplate.Replace("{recordurl}", orgUrl + "/main.aspx?" + "etn=" + record.LogicalName + "&id=%7B" + record.Id + "%7D" + "&pagetype=entityrecord" + "&forceUCI=1");
                        }
                    }

                    // final step - remove all occuring strings by "{ and }" - effectively blanking the unmapped schemas
                    string result = jsonTemplate;
                    while (true)
                    {
                        int indexOfOpen  = result.IndexOf("\"{");
                        int indexOfClose = result.IndexOf("}\"", indexOfOpen + 1);

                        if (indexOfOpen < 0 && indexOfClose < 0)
                        {
                            break;
                        }
                        result = result.Substring(0, indexOfOpen) + "\"" + result.Substring(indexOfClose + 1);
                    }

                    if (result != jsonTemplate)
                    {
                        jsonTemplate = result;
                    }
                }
                return(jsonTemplate);
            }
            catch (Exception e)
            {
                throw new Exception("SS21.Examples.TeamBot.AdaptiveCardFactory.MapAttributesToJsonTemplate :: ERROR :: Unable to map attributes to JSON template due to the following reason/s " + Environment.NewLine + e.Message);
            }
        }
        public static string ProcessDynamicContent(Microsoft.Xrm.Sdk.Entity record, string jsonTemplate)
        {
            try
            {
                JObject jobject = JObject.Parse(jsonTemplate);

                JArray a        = JArray.Parse(jobject["body"].ToString());
                JArray newArray = new JArray();

                foreach (JObject o in a.Children <JObject>())
                {
                    bool   dynamicContent = false;
                    string schemaName     = string.Empty;

                    foreach (JProperty p in o.Properties())
                    {
                        if (p.Name.Equals("dynamicContent"))
                        {
                            dynamicContent = true;
                        }
                        if (p.Name.Equals("text"))
                        {
                            // extract schema name between { } ex. {description}
                            // schemaName = description
                            schemaName = (string)o["text"];

                            if (!string.IsNullOrEmpty(schemaName))
                            {
                                schemaName = schemaName.Substring(1, schemaName.Length - 2);
                            }
                        }
                    }

                    // placeholder json for new textbox element
                    string jsonElement = @"{
                         ""type"": ""TextBlock"",
                         ""text"": """",
                         ""wrap"": true,
                         }";

                    if (!String.IsNullOrEmpty(schemaName))
                    {
                        // get value by schema name from Record
                        if (record.Contains(schemaName))
                        {
                            string fieldValue = (string)record[schemaName];

                            // remove html and perform string split
                            fieldValue = ConvertHTMLToText(fieldValue);

                            if (record.LogicalName == "email")
                            {
                                // remove any emails after the first detected email in the chain
                                int stringPosition = fieldValue.IndexOf("From:");

                                if (stringPosition != -1)
                                {
                                    fieldValue = fieldValue.Substring(0, stringPosition);
                                }

                                // attempt to remove signature by mapping from name
                                Microsoft.Xrm.Sdk.EntityCollection collection = (Microsoft.Xrm.Sdk.EntityCollection)record["from"];
                                string fromValue = collection.ToCommaSeparatedString();
                                stringPosition = fieldValue.IndexOf(fromValue);

                                if (stringPosition != -1)
                                {
                                    fieldValue = fieldValue.Substring(0, stringPosition);
                                }
                            }

                            // dodge - replace multiple line break characters with a unique break string
                            fieldValue = Regex.Replace(fieldValue, "[\r\n\f]", "/crmcs/", System.Text.RegularExpressions.RegexOptions.IgnoreCase);

                            string[] fieldValues = fieldValue.Split(new string[] { "/crmcs/" }, StringSplitOptions.None);

                            for (int i = 0; i < fieldValues.Length; i++)
                            {
                                string value = fieldValues[i];

                                if (!string.IsNullOrEmpty(value))
                                {
                                    JObject newElement = null;

                                    if (i == 0)
                                    {
                                        // first value to replace current element
                                        newElement = o;
                                    }
                                    else
                                    {
                                        // next value set as new textbox element
                                        newElement = JObject.Parse(jsonElement);
                                    }
                                    newElement["text"] = value;
                                    newArray.Add(newElement);
                                }
                            }
                        }
                        else
                        {
                            // do nothing
                        }
                    }
                    else
                    {
                        newArray.Add(o);
                    }
                }

                jobject["body"] = newArray;

                // return formatted JSON Template as string to keep things consistent
                return(jobject.ToString());
            }
            catch (Exception ex)
            {
                throw new Exception("ProcessDynamicContent :: " + ex.Message);
            }
        }