private string GetTargetField(FileInfo fileInfo, string recordType)
        {
            //adx_webtemplate -> adx_source (Source)
            //adx_entitylist -> adx_registerstartupscript (Custom JavaScript)
            //adx_webpage -> adx_customjavascript (Custom JavaScript)
            //adx_webpage -> adx_customcss (Custom CSS)

            if (recordType == "adx_webfile")
            {
                return("adx_source");
            }
            if (fileInfo.Name.EndsWith("css"))
            {
                var matchingFields = Service.GetFields(recordType).Where(f => f.Contains("css"));
                if (matchingFields.Count() != 1)
                {
                    throw new Exception($"Could not find unique field in {recordType} with name containing 'css'");
                }
                return(matchingFields.First());
            }
            if (fileInfo.Name.EndsWith("js"))
            {
                var matchingFields = Service.GetFields(recordType).Where(f => Service.GetFieldLabel(f, recordType)?.ToLower()?.Contains("javascript") ?? false);
                if (matchingFields.Count() != 1)
                {
                    throw new Exception($"Could not find unique field in {recordType} where label contains 'javascript'");
                }
                return(matchingFields.First());
            }
            if (fileInfo.Name.EndsWith("htm") || fileInfo.Name.EndsWith("html"))
            {
                if (recordType == Entities.adx_webpage)
                {
                    return("adx_copy");
                }
                if (recordType == Entities.adx_contentsnippet)
                {
                    return("adx_value");
                }
                var matchingFields = Service.GetFields(recordType).Where(f => f.Contains("source"));
                if (matchingFields.Count() != 1)
                {
                    throw new Exception($"Could not find unique field in {recordType} with name containing 'source'");
                }
                return(matchingFields.First());
            }
            throw new NotImplementedException($"The file extention {fileInfo.Extension} is not implemented");
        }
        private void Load(string assemblyName)
        {
            LoadingViewModel.LoadingMessage = "Loading Assembly";

            var assemblyRecord = XrmRecordService.GetFirst(Entities.pluginassembly, Fields.pluginassembly_.name,
                                                           assemblyName);

            if (assemblyRecord == null)
            {
                throw new NullReferenceException("Assembly Not Deployed");
            }

            LoadingViewModel.LoadingMessage = "Loading Plugin Types";

            var pluginTypes = XrmRecordService.RetrieveAllAndClauses(Entities.plugintype,
                                                                     new[] { new Condition(Fields.plugintype_.pluginassemblyid, ConditionType.Equal, assemblyRecord.Id) });

            if (!pluginTypes.Any())
            {
                throw new NullReferenceException("Not Plugin Types Deployed For Assembly");
            }

            LoadingViewModel.LoadingMessage = "Loading Plugin Triggers";

            SdkMessageStepsPre = XrmRecordService.RetrieveAllOrClauses(Entities.sdkmessageprocessingstep,
                                                                       pluginTypes.Select(
                                                                           pt => new Condition(Fields.sdkmessageprocessingstep_.plugintypeid, ConditionType.Equal, pt.Id)));
            var sdkMessageStepsWithFilter = SdkMessageStepsPre
                                            .Where(sms => sms.GetField(Fields.sdkmessageprocessingstep_.sdkmessagefilterid) != null);

            LoadingViewModel.LoadingMessage = "Loading Plugin Filters";

            var filters = !sdkMessageStepsWithFilter.Any()
                ? new IRecord[0]
                : XrmRecordService.RetrieveAllOrClauses(Entities.sdkmessagefilter,
                                                        sdkMessageStepsWithFilter.Select(
                                                            sms =>
                                                            new Condition(Fields.sdkmessagefilter_.sdkmessagefilterid, ConditionType.Equal,
                                                                          sms.GetLookupId(Fields.sdkmessageprocessingstep_.sdkmessagefilterid))));

            LoadingViewModel.LoadingMessage = "Loading Plugin Images";

            var preImages = SdkMessageStepsPre.Any()
                ? XrmRecordService.RetrieveAllOrClauses(Entities.sdkmessageprocessingstepimage, SdkMessageStepsPre.Select(m => new Condition(Fields.sdkmessageprocessingstepimage_.sdkmessageprocessingstepid, ConditionType.Equal, m.Id)))
                            .Where(i => i.GetOptionKey(Fields.sdkmessageprocessingstepimage_.imagetype) == OptionSets.SdkMessageProcessingStepImage.ImageType.PreImage.ToString())
                            .GroupBy(i => i.GetLookupField(Fields.sdkmessageprocessingstepimage_.sdkmessageprocessingstepid))
                            .Where(g => g.Key != null && g.Key.Id != null)
                            .ToDictionary(i => i.Key.Id, g => g.First())
                : new Dictionary <string, IRecord>();

            _entryObject = new PluginTriggers();
            var triggers = new List <PluginTrigger>();

            foreach (var item in SdkMessageStepsPre)
            {
                var filterId        = item.GetLookupId(Fields.sdkmessageprocessingstep_.sdkmessagefilterid);
                var matchingFilters = filters.Where(f => f.Id == filterId);
                var filter          = matchingFilters.Any() ? matchingFilters.First() : null;
                var recordType      = filter == null ? null : filter.GetStringField(Fields.sdkmessagefilter_.primaryobjecttypecode);
                LoadingViewModel.LoadingMessage = $"Loading {XrmRecordService.GetDisplayName(recordType)} Type";
                RecordType recordTypeObj = null;
                try
                {
                    recordTypeObj = new RecordType(recordType, XrmRecordService.GetDisplayName(recordType));
                }
                catch (Exception)
                {
                }

                var rank  = item.GetIntegerField(Fields.sdkmessageprocessingstep_.rank);
                var name  = item.GetStringField(Fields.sdkmessageprocessingstep_.name);
                var stage = item.GetOptionKey(Fields.sdkmessageprocessingstep_.stage);
                var mode  = item.GetOptionKey(Fields.sdkmessageprocessingstep_.mode);
                var filteringAttributesString = item.GetStringField(Fields.sdkmessageprocessingstep_.filteringattributes);

                var trigger = new PluginTrigger();
                //load trigger details
                trigger.Id = item.Id;
                //for some unknown reason this field was setting the target type ot sdkmessage filter
                //despite the target being plugin type so I had to implement this to correct the type
                //the name is popuated after the loop
                trigger.Message = filter == null ? null : filter.GetLookupField(Fields.sdkmessagefilter_.sdkmessageid);
                item.SetField(Fields.sdkmessageprocessingstep_.plugintypeid, new Lookup(Entities.plugintype, item.GetLookupId(Fields.sdkmessageprocessingstep_.plugintypeid), null), XrmRecordService);
                trigger.Plugin          = item.GetLookupField(Fields.sdkmessageprocessingstep_.plugintypeid);
                trigger.RecordType      = recordTypeObj;
                trigger.Stage           = stage.ParseEnum <PluginTrigger.PluginStage>();
                trigger.Mode            = mode.ParseEnum <PluginTrigger.PluginMode>();
                trigger.Rank            = rank;
                trigger.FilteringFields = filteringAttributesString == null
                    ? new RecordField[0]
                    : filteringAttributesString.Split(',')
                                          .Select(s => s.Trim())
                                          .Where(s => !string.IsNullOrWhiteSpace(s))
                                          .Select(s => new RecordField(s, XrmRecordService.GetFieldLabel(s, recordType)))
                                          .ToArray();
                trigger.SpecificUserContext = item.GetLookupField(Fields.sdkmessageprocessingstep_.impersonatinguserid);
                //load image details if there is one
                if (trigger.Id != null)
                {
                    if (!preImages.ContainsKey(item.Id))
                    {
                        trigger.PreImageAllFields = false;
                    }
                    else
                    {
                        var preImage   = preImages[item.Id];
                        var attributes = preImage.GetStringField(Fields.sdkmessageprocessingstepimage_.attributes);
                        trigger.PreImageAllFields = string.IsNullOrWhiteSpace(attributes);
                        trigger.PreImageFields    = attributes == null
                            ? new RecordField[0]
                            : attributes
                                                    .Split(',')
                                                    .Select(s => s.Trim())
                                                    .Where(s => !string.IsNullOrWhiteSpace(s))
                                                    .Select(s => new RecordField(s, XrmRecordService.GetFieldLabel(s, recordType)))
                                                    .ToArray();
                        trigger.PreImageName = preImage.GetStringField(Fields.sdkmessageprocessingstepimage_.entityalias);
                        trigger.PreImageId   = preImage.Id;
                    }
                }
                triggers.Add(trigger);
            }
            LoadingViewModel.LoadingMessage = "Loading Plugin Names";
            //since I had to correct the target type for this fields lookup need to populate the name
            if (triggers.Any())
            {
                XrmRecordService.PopulateLookups(new Dictionary <string, List <Lookup> >()
                {
                    { Fields.sdkmessageprocessingstep_.plugintypeid, triggers.Select(t => t.Plugin).ToList() }
                }, null);
            }
            triggers = triggers
                       .OrderBy(t => t.RecordType?.Value)
                       .ThenBy(t => t.Message?.Name)
                       .ThenByDescending(t => t.Stage)
                       .ThenByDescending(t => t.Mode).ToList();
            EntryObject.Triggers = triggers;
            EntryObject.Assembly = assemblyRecord.ToLookup();

            LoadingViewModel.LoadingMessage = "Loading Plugins Into Grid";
        }
        private void VerifyFields(CustomisationImportRequest request)
        {
            var response = new CustomisationImportResponse();

            var optionMetadata =
                CustomisationImportService.ExtractOptionSetsFromExcel(request.ExcelFile.FileName, Controller, response);
            var fieldMetadata =
                CustomisationImportService.ExtractFieldMetadataFromExcel(request.ExcelFile.FileName, Controller,
                                                                         optionMetadata, response).Values;

            foreach (var field in fieldMetadata)
            {
                Assert.IsTrue(XrmRecordService.FieldExists(field.SchemaName, field.RecordType));
                Assert.IsTrue(XrmRecordService.GetFieldLabel(field.SchemaName, field.RecordType) ==
                              field.DisplayName);
                Assert.IsTrue(XrmRecordService.GetFieldMetadata(field.SchemaName, field.RecordType).Description ==
                              field.Description);
                Assert.IsTrue(XrmRecordService.GetFieldMetadata(field.SchemaName, field.RecordType).IsMandatory ==
                              field.IsMandatory);
                Assert.IsTrue(XrmRecordService.GetFieldMetadata(field.SchemaName, field.RecordType).Audit ==
                              field.Audit);
                Assert.IsTrue(XrmRecordService.GetFieldMetadata(field.SchemaName, field.RecordType).Searchable ==
                              field.Searchable);
                if (field.FieldType == RecordFieldType.String)
                {
                    Assert.IsTrue(XrmRecordService.GetMaxLength(field.SchemaName, field.RecordType) ==
                                  ((StringFieldMetadata)field).MaxLength);
                    Assert.IsTrue(XrmRecordService.GetFieldMetadata(field.SchemaName, field.RecordType).TextFormat ==
                                  ((StringFieldMetadata)field).TextFormat);
                }
                if (field.FieldType == RecordFieldType.Integer)
                {
                    Assert.IsTrue(XrmRecordService.GetFieldMetadata(field.SchemaName, field.RecordType).MinValue ==
                                  ((IntegerFieldMetadata)field).MinValue);
                    Assert.IsTrue(XrmRecordService.GetFieldMetadata(field.SchemaName, field.RecordType).MaxValue ==
                                  ((IntegerFieldMetadata)field).MaxValue);
                    Assert.IsTrue(XrmRecordService.GetFieldMetadata(field.SchemaName, field.RecordType).IntegerFormat ==
                                  ((IntegerFieldMetadata)field).IntegerFormat);
                }
                if (field.FieldType == RecordFieldType.Decimal)
                {
                    Assert.IsTrue(XrmRecordService.GetFieldMetadata(field.SchemaName, field.RecordType).MinValue ==
                                  ((DecimalFieldMetadata)field).MinValue);
                    Assert.IsTrue(XrmRecordService.GetFieldMetadata(field.SchemaName, field.RecordType).MaxValue ==
                                  ((DecimalFieldMetadata)field).MaxValue);
                    Assert.IsTrue(XrmRecordService.GetFieldMetadata(field.SchemaName, field.RecordType).DecimalPrecision ==
                                  ((DecimalFieldMetadata)field).DecimalPrecision);
                }
                if (field.FieldType == RecordFieldType.Date)
                {
                    Assert.IsTrue(XrmRecordService.GetFieldMetadata(field.SchemaName, field.RecordType).IncludeTime ==
                                  ((DateFieldMetadata)field).IncludeTime);
                    Assert.IsTrue(XrmRecordService.GetFieldMetadata(field.SchemaName, field.RecordType).DateBehaviour ==
                                  ((DateFieldMetadata)field).DateBehaviour);
                }
                if (field.FieldType == RecordFieldType.Picklist)
                {
                    var actualOptions = XrmRecordService.GetPicklistKeyValues(field.SchemaName,
                                                                              field.RecordType);
                    var expectedOption = ((PicklistFieldMetadata)field).PicklistOptions;
                    VerifyOptionSetsEqual(actualOptions, expectedOption);
                    Assert.AreEqual(field.IsMultiSelect, XrmRecordService.GetFieldMetadata(field.SchemaName, field.RecordType).IsMultiSelect);
                }
                if (field.FieldType == RecordFieldType.Double)
                {
                    Assert.IsTrue(XrmRecordService.GetFieldMetadata(field.SchemaName, field.RecordType).MinValue ==
                                  ((DoubleFieldMetadata)field).MinValue);
                    Assert.IsTrue(XrmRecordService.GetFieldMetadata(field.SchemaName, field.RecordType).MaxValue ==
                                  ((DoubleFieldMetadata)field).MaxValue);
                    Assert.IsTrue(XrmRecordService.GetFieldMetadata(field.SchemaName, field.RecordType).DecimalPrecision ==
                                  ((DoubleFieldMetadata)field).DecimalPrecision);
                }
            }
        }