/// <summary>
        /// Batch update those failed keys!
        /// </summary>
        /// <param name="keys"></param>
        private void ReactivateKeys(List <EntityKeyMetadata> keys)
        {
            WorkAsync(new WorkAsyncInfo {
                Message       = "Reactivating Entity Keys",
                AsyncArgument = keys,
                IsCancelable  = true,
                MessageWidth  = 340,
                MessageHeight = 150,
                Work          = (w, e) =>
                {
                    w.ReportProgress(0, $"Reactivating Entity Keys");

                    var results = CrmActions.ReactivateEntityKey(Service, keys);

                    w.ReportProgress(100, $"Reactivating Entity Keys complete!");
                    e.Result = results;
                },
                ProgressChanged = e => {
                    SendMessageToStatusBar?.Invoke(this, new StatusBarMessageEventArgs(e.ProgressPercentage, e.UserState.ToString()));
                },
                PostWorkCallBack = e => {
                    // reload the list of selected entities
                    if (e.Result != null)
                    {
                        var errors = (List <string>)e.Result;
                        MessageBox.Show(this, $"The following errors occurred while attempting to activate\n{string.Join("\n", errors)}");
                    }

                    // reload the list now that have made the call
                    LoadSelectedEntityKeys();
                }
            });
        }
示例#2
0
        public void ProcessWhoAmI()
        {
            tsbCancel.Enabled = true;

            WorkAsync(new WorkAsyncInfo
            {
                Message = "Retrieving your user id...",
                Work    = (w, e) =>
                {
                    var list = new Dictionary <ConnectionDetail, Guid>();

                    // Process initial connection
                    var request  = new WhoAmIRequest();
                    var response = (WhoAmIResponse)Service.Execute(request);

                    list.Add(ConnectionDetail, response.UserId);

                    // Process additional connections
                    foreach (var detail in AdditionalConnectionDetails)
                    {
                        if (w.CancellationPending)
                        {
                            e.Cancel = true;
                        }

                        w.ReportProgress(0, $"Processing organization {detail.OrganizationFriendlyName}...");

                        request  = new WhoAmIRequest();
                        response = (WhoAmIResponse)detail.GetCrmServiceClient().Execute(request);

                        list.Add(detail, response.UserId);
                        e.Result = list;
                    }
                },
                ProgressChanged = e =>
                {
                    // If progress has to be notified to user, use the following method:
                    //SetWorkingMessage("Message to display");

                    // If progress has to be notified to user, through the
                    // status bar, use the following method
                    SendMessageToStatusBar?.Invoke(this, new StatusBarMessageEventArgs(e.UserState.ToString()));
                },
                PostWorkCallBack = e =>
                {
                    SendMessageToStatusBar?.Invoke(this, new StatusBarMessageEventArgs(""));
                    tsbCancel.Enabled = false;

                    var list = (Dictionary <ConnectionDetail, Guid>)e.Result;
                    foreach (ListViewItem item in listView1.Items)
                    {
                        item.SubItems.Add(list[(ConnectionDetail)item.Tag].ToString("B"));
                    }
                },
                AsyncArgument = null,
                IsCancelable  = true,
                MessageWidth  = 340,
                MessageHeight = 150
            });
        }
        /// <summary>
        /// Retrieve the Attribute metadata for the given EntityLogicalName
        /// </summary>
        /// <param name="entityLogicalName"></param>
        private void RetrieveEntityAttributes(string entityLogicalName)
        {
            // lock thing down
            ToggleNewKeyPaneEnabled(false);

            WorkAsync(new WorkAsyncInfo {
                Message       = "Retriveing Entity Attributes",
                AsyncArgument = entityLogicalName,
                IsCancelable  = true,
                MessageWidth  = 340,
                MessageHeight = 150,
                Work          = (w, e) => {
                    var entLogicalName = e.Argument as string;

                    w.ReportProgress(0, $"Retriveing Entity Attributes");

                    var results = CrmActions.RetrieveEntity(Service, entLogicalName, true);

                    w.ReportProgress(100, $"Retriveing Entity Attributes complete!");

                    e.Result = results;
                },
                ProgressChanged = e => {
                    SendMessageToStatusBar?.Invoke(this, new StatusBarMessageEventArgs(e.ProgressPercentage, e.UserState.ToString()));
                },
                PostWorkCallBack = e => {
                    var entity = e.Result as EntityMetadata;
                    PopulateEntityAttributes(entity);
                }
            });
        }
        private void RunEMR(OrganizationRequest or, BackgroundWorker w)
        {
            //string message = "";
            requestWithResults.Requests.Add(or);
            emrCount++;
            if (requestWithResults.Requests.Count >= emrBatchSize)
            {
                DateTime start = DateTime.Now;

                //w.ReportProgress(0, string.Format("Starting Workflows: {0} of {1}{2}Est. Time Remaining: {3}", emrCount.ToString("#,#", CultureInfo.InvariantCulture)
                //, ExecutionRecordSet.Entities.Count.ToString("#,#", CultureInfo.InvariantCulture), Environment.NewLine, estTS.ToString("hh\\:mm\\:ss")));
                //message = string.Format("Deleting Records: {0} of {1}{2}Est. Time Remaining: {3}", emrCount.ToString("#,#", CultureInfo.InvariantCulture)
                //    , ExecutionRecordSet.Entities.Count.ToString("#,#", CultureInfo.InvariantCulture), Environment.NewLine, estTS.ToString("hh\\:mm\\:ss"));

                ExecuteMultipleResponse emrsp = (ExecuteMultipleResponse)Service.Execute(requestWithResults);
                HandleErrors(emrsp);
                requestWithResults.Requests.Clear();

                DateTime end = DateTime.Now;
                TimeSpan ts  = end - start;
                _listTS.Add(ts);

                double doubleAverageTicks = _listTS.Average(timeSpan => timeSpan.Ticks);
                long   longAverageTicks   = Convert.ToInt64(doubleAverageTicks);
                avgTS = new TimeSpan(longAverageTicks);
                estTS = new TimeSpan(((ExecutionRecordSet.Entities.Count - emrCount) / emrBatchSize) * avgTS.Ticks);

                w.ReportProgress(0, GetDeleteStatusMessage(ExecutionRecordSet.Entities[0].LogicalName, emrCount, ExecutionRecordSet.Entities.Count, estTS));
                double progValue = (((double)emrCount / (double)ExecutionRecordSet.Entities.Count) * 100);
                //SendMessageToStatusBar?.Invoke(this, new StatusBarMessageEventArgs(Convert.ToInt32(Math.Round(progValue)), $"{emrCount.ToString("#,#", CultureInfo.InvariantCulture)} / {ExecutionRecordSet.Entities.Count.ToString("#,#", CultureInfo.InvariantCulture)}"));
                SendMessageToStatusBar?.Invoke(this, new StatusBarMessageEventArgs(Convert.ToInt32(Math.Round(progValue)), null));
            }
            //return message;
        }
        /// <summary>
        /// Commit the selected updates to the server
        /// </summary>
        public void SaveChanges()
        {
            var execMulti = new ExecuteMultipleRequest()
            {
                Settings = new ExecuteMultipleSettings()
                {
                    ContinueOnError = true,
                    ReturnResponses = true
                },
                Requests = new OrganizationRequestCollection()
            };

            // now make the inserts
            foreach (ListViewItem item in listViewPreview.CheckedItems)
            {
                var ent = item.Tag as PendingChange;

                if (ent.Entity.EntityState == EntityState.Created)
                {
                    execMulti.Requests.Add(new CreateRequest()
                    {
                        Target = ent.Entity
                    });
                }
                else if (ent.Entity.EntityState == EntityState.Changed)
                {
                    execMulti.Requests.Add(new UpdateRequest()
                    {
                        Target = ent.Entity
                    });
                }
            }

            WorkAsync(
                new WorkAsyncInfo()
            {
                AsyncArgument = execMulti,
                Message       = "Updating Portal Site Settings Records",
                MessageWidth  = 340,
                MessageHeight = 150,
                Work          = (w, e) =>
                {
                    var req  = e.Argument as ExecuteMultipleRequest;
                    var resp = Service.Execute(req) as ExecuteMultipleResponse;
                    e.Result = resp;
                },
                ProgressChanged = e =>
                {
                    SendMessageToStatusBar?.Invoke(this, new StatusBarMessageEventArgs(e.ProgressPercentage, e.UserState.ToString()));
                },
                PostWorkCallBack = e =>
                {
                    // _currSiteSettingsColl = e.Result as EntityCollection;
                    LoadCurrentWebsiteSettings();
                }
            });
        }
        public CrmAttributeSelectionControl()
        {
            InitializeComponent();

            m_progressIndicator = new ProgressIndicator(new Action <StatusBarMessageEventArgs>((message) =>
            {
                SendMessageToStatusBar?.Invoke(this, message);
            }));
        }
示例#7
0
        public void LoadEntities()
        {
            lvEntities.Items.Clear();
            lvEntities.Enabled       = false;
            tsbLoadEntities.Enabled  = false;
            tsbExportToExcel.Enabled = false;

            WorkAsync(new WorkAsyncInfo
            {
                Message = "Loading Entities...",
                Work    = (w, e) =>
                {
                    e.Result = MetadataHelper.LoadEntities(Service);
                },
                PostWorkCallBack = e =>
                {
                    if (e.Error != null)
                    {
                        MessageBox.Show(e.Error.ToString());
                    }

                    var items = new List <ListViewItem>();

                    entities = (EntityMetadataCollection)e.Result;

                    foreach (var emd in entities)
                    {
                        var item = new ListViewItem(emd.DisplayName.UserLocalizedLabel != null
                            ? emd.DisplayName.UserLocalizedLabel.Label
                            : "N/A");
                        item.SubItems.Add(emd.LogicalName);
                        item.Tag = emd;

                        allItems.Add(item);

                        if (txtSearch.Text.Length == 0 || txtSearch.Text.Length > 0 &&
                            (emd.LogicalName.IndexOf(txtSearch.Text.ToLower(), StringComparison.Ordinal) >= 0 ||
                             emd.DisplayName?.UserLocalizedLabel?.Label.ToLower()
                             .IndexOf(txtSearch.Text.ToLower(), StringComparison.Ordinal) >= 0))
                        {
                            items.Add(item);
                        }
                    }

                    lvEntities.Items.AddRange(items.ToArray());
                    lvEntities.Enabled       = true;
                    tsbLoadEntities.Enabled  = true;
                    tsbExportToExcel.Enabled = true;
                },
                ProgressChanged = e =>
                {
                    SendMessageToStatusBar?.Invoke(this, new StatusBarMessageEventArgs(e.UserState.ToString()));
                }
            });
        }
示例#8
0
        private void ExecuteMultipleRequests(List <OrganizationRequest> requests)
        {
            WorkAsync(new WorkAsyncInfo
            {
                Message = "Creating entity records",
                Work    = (worker, args) =>
                {
                    var responses = new ExecuteMultipleResponseItemCollection();
                    var lists     = SplitList(requests);
                    var count     = 0;
                    foreach (var list in lists)
                    {
                        var collection = new OrganizationRequestCollection();
                        collection.AddRange(list);
                        var req = new ExecuteMultipleRequest
                        {
                            Requests = collection,
                            Settings = new ExecuteMultipleSettings {
                                ContinueOnError = true, ReturnResponses = false
                            }
                        };
                        count++;
                        var response = (ExecuteMultipleResponse)Service.Execute(req);
                        SendMessageToStatusBar?.Invoke(this, new StatusBarMessageEventArgs(count / requests.Count, $"{count}/{requests.Count} records created"));
                        responses.AddRange(response.Responses);
                    }

                    args.Result = responses;
                },
                PostWorkCallBack = (args) =>
                {
                    if (args.Error != null)
                    {
                        MessageBox.Show($"Something bad happened. Error message:\n{args.Error}", @"Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        return;
                    }
                    var result = (ExecuteMultipleResponseItemCollection)args.Result;
                    if (result.Count == 0)
                    {
                        MessageBox.Show($"{requests.Count} records successfully created");
                    }
                    else
                    {
                        var createdCount = requests.Count - result.Count;
                        MessageBox.Show($"{createdCount}/{requests.Count} records created. See error log for details.");

                        foreach (var response in result)
                        {
                            LogError(response.Fault.Message);
                        }
                    }
                },
                IsCancelable = true,
            });
        }
示例#9
0
        private void StatusBarMessager_SendMessageToStatusBar(object sender, StatusBarMessageEventArgs e)
        {
            void Mi()
            {
                lastStatusEventArgs = e;

                if (DockState != DockState.Float)
                {
                    statusStrip1.Visible = false;
                    SendMessageToStatusBar?.Invoke(sender, e);
                    return;
                }

                SendMessageToStatusBar?.Invoke(sender, new StatusBarMessageEventArgs(null, null));

                statusStrip1.Visible = true;

                if (string.IsNullOrEmpty(e.Message) && e.Progress == null)
                {
                    statusStrip1.Visible = false;
                }
                else if (!string.IsNullOrEmpty(e.Message) && e.Progress != null)
                {
                    toolStripProgressBar.Value   = e.Progress.Value;
                    toolStripStatusLabel.Text    = e.Message;
                    toolStripProgressBar.Visible = true;
                    toolStripStatusLabel.Visible = true;
                    statusStrip1.Visible         = true;
                }
                else if (!string.IsNullOrEmpty(e.Message))
                {
                    toolStripStatusLabel.Text    = e.Message;
                    toolStripStatusLabel.Visible = true;
                    toolStripProgressBar.Visible = false;
                    statusStrip1.Visible         = true;
                }
                else if (e.Progress != null)
                {
                    toolStripProgressBar.Value   = e.Progress.Value;
                    toolStripProgressBar.Visible = true;
                    toolStripStatusLabel.Visible = false;
                    statusStrip1.Visible         = true;
                }
            }

            if (statusStrip1.InvokeRequired)
            {
                statusStrip1.Invoke((MethodInvoker)Mi);
            }
            else
            {
                Mi();
            }
        }
        private void ProgressChanged(ProgressChangedEventArgs progressChangedEventArgs)
        {
            SetWorkingMessage(string.Format("{0}% complete", progressChangedEventArgs.ProgressPercentage));
            int tic = 1;

            if (progressChangedEventArgs.ProgressPercentage > 0)
            {
                tic += progressChangedEventArgs.ProgressPercentage % 3;
            }
            SendMessageToStatusBar?.Invoke(this, new StatusBarMessageEventArgs(progressChangedEventArgs.ProgressPercentage, "Loading" + new string('.', tic)));
        }
示例#11
0
        public string CreateAllData(int totalRecordCount, List <SimpleRow> maps, string entityName, BackgroundWorker wrker, SetItem setItem)
        {
            int initialCount     = totalRecordCount;
            int recordCount      = totalRecordCount > 500 ? 500 : totalRecordCount;
            int noRuns           = (int)Math.Ceiling((double)totalRecordCount / (double)recordCount);
            int percDone         = 0;
            var entityCollection = new EntityCollection {
                EntityName = entityName
            };
            var mockClass = new ExpandoObject();

            foreach (var map in maps)
            {
                ((IDictionary <string, object>)mockClass)[map.LogicalName] = map.SelectedMock;
            }

            wrker.ReportProgress(0, "Getting Mockaroo Data for " + entityName);
            var    client = new MockClient(txtMockKey.Text);
            string errors = string.Empty;

            if (collection != null && collection.Entities.Count > 0)
            {
                recordCount = collection.Entities.Count;
                wrker.ReportProgress(percDone, "Creating Sample Data");
                errors           += CreateData(collection, wrker, setItem, entityName);
                totalRecordCount -= recordCount;
                SendMessageToStatusBar?.Invoke(this, new StatusBarMessageEventArgs(
                                                   (int)Math.Round((double)(initialCount - totalRecordCount) * 100 / initialCount),
                                                   $"{totalRecordCount} {entityName} Records remaining"));
            }
            while (totalRecordCount > 0)
            {
                recordCount = totalRecordCount > 1000 ? 1000 : totalRecordCount;
                List <ExpandoObject> returnData = client.GetData(mockClass, recordCount);
                wrker.ReportProgress(percDone, "Got Data, Generating Entity Collection");
                foreach (List <ExpandoObject> subList in SplitList(returnData))
                {
                    entityCollection = CreateEntityCollection(subList, entityName, maps);
                    wrker.ReportProgress(percDone, "Retrieved Mockaroo Data, Creating in Dataverse");
                    percDone += 100 / noRuns;
                    errors   += CreateData(entityCollection, wrker, setItem, entityName);

                    totalRecordCount -= subList.Count();
                    SendMessageToStatusBar?.Invoke(this, new StatusBarMessageEventArgs(
                                                       (int)Math.Round((double)(initialCount - totalRecordCount) * 100 / initialCount),
                                                       $"{totalRecordCount} {entityName} Records remaining"));
                    wrker.ReportProgress(percDone, "Created Data");
                }
            }

            return(errors);
        }
示例#12
0
        /// <summary>
        /// Retrieves dedupe rules from the source organization
        /// </summary>
        private void RetrieveDedupeRules()
        {
            lvDedupeRules.Items.Clear();

            tsbLoadDupeRules.Enabled     = false;
            tsbTransferDupeRules.Enabled = false;
            btnSelectTarget.Enabled      = false;
            Cursor = Cursors.WaitCursor;

            SendMessageToStatusBar?.Invoke(this, new StatusBarMessageEventArgs("Loading dedupe rules..."));

            var bw = new BackgroundWorker();

            bw.DoWork += (sender, e) =>
            {
                e.Result = _drManager.GetDedupeRules(Service);
            };
            bw.RunWorkerCompleted += (sender, e) =>
            {
                if (e.Error == null)
                {
                    //var distinctRules = ((List<Entity>) e.Result).DistinctBy(rule => rule.GetAttributeValue<string>("name"));
                    var distinctRules = ((List <Entity>)e.Result).GroupBy(x => x.Id);
                    foreach (var dedupeRule in distinctRules)
                    {
                        var item1 = new ListViewItem
                        {
                            Tag = dedupeRule, Text = dedupeRule.First().GetAttributeValue <string>("name"), ToolTipText = this.Text
                        };
                        item1.SubItems.Add(dedupeRule.First().GetAttributeValue <string>("baseentityname"));
                        item1.SubItems.Add(dedupeRule.First().GetAttributeValue <string>("matchingentityname"));
                        item1.SubItems.Add(dedupeRule.First().FormattedValues["statecode"]);

                        lvDedupeRules.Items.Add(item1);
                    }
                }
                else
                {
                    MessageBox.Show(ParentForm, @"An error has occured while loading dedupe rules: " + e.Error.Message, @"Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }

                tsbLoadDupeRules.Enabled     = true;
                tsbTransferDupeRules.Enabled = true;
                btnSelectTarget.Enabled      = true;
                Cursor = Cursors.Default;

                SendMessageToStatusBar?.Invoke(this, new StatusBarMessageEventArgs(string.Empty));
            };
            bw.RunWorkerAsync();
        }
        public void LoadAttributes()
        {
            fullListOfAttributes.Clear(); // Clear all the existing ones
            lvAttributes.Items.Clear();
            lvAttributes.Enabled      = false;
            tsbClose.Enabled          = false;
            tsbLoadAttributes.Enabled = false;
            gwAttributes.Enabled      = false;

            DisplayMessageCentralPanel(MessageType.Infor, "Loading attributes from Dynamics 365. Please wait...");
            WorkAsync(new WorkAsyncInfo
            {
                Message = "Loading attributes please wait...",
                Work    = (w, e) =>
                {
                    e.Result = Helpers.MetaDataHelper.LoadAttributes(Service);
                },
                PostWorkCallBack = e =>
                {
                    if (e.Error != null)
                    {
                        MessageBox.Show(e.Error.ToString());
                    }

                    fullListOfAttributes.AddRange((List <AttributeViewModel>)e.Result);

                    cbxListEntities.DataSource       = fullListOfAttributes.Select(x => x.EntityLogicalName).Distinct().OrderBy(y => y).ToList();
                    cbxListAttributeTypes.DataSource =
                        fullListOfAttributes.Select(x => x.AttributeType).Distinct().OrderBy(y => y).ToList();

                    txtSearch.Enabled = true;
                    DisplayMessageCentralPanel(MessageType.Infor,
                                               $"Attributes have been loaded successfully. " +
                                               $"{Environment.NewLine} {Environment.NewLine} Found total of {fullListOfAttributes.Count} attributes. " +
                                               $"{Environment.NewLine} {Environment.NewLine} Please use the Search bar to find attributes you are looking for.");

                    gwAttributes.DataSource = fullListOfAttributes;
                    gwAttributes.Refresh();
                    gwAttributes.Enabled = true;

                    tsbClose.Enabled          = true;
                    tsbLoadAttributes.Enabled = true;
                },
                ProgressChanged = e =>
                {
                    SendMessageToStatusBar?.Invoke(this, new StatusBarMessageEventArgs(e.UserState.ToString()));
                }
            });
        }
        private void LoadEntities()
        {
            _systemComparer = new Logic.SystemComparer(SourceConnection, TargetConnection);

            WorkAsync(new WorkAsyncInfo
            {
                Message = "Getting Metadata",
                Work    = (worker, args) =>
                {
                    LogInfo("Start retrieving metadata on Source");
                    SendMessageToStatusBar?.Invoke(this, new StatusBarMessageEventArgs(0, $"Fetching Metadata from Source {(_configuration.IncludeAllMetadata ? "with Attributes" : "without Attributes")}..."));
                    _systemComparer.RetrieveMetadata(ConnectionType.Source, _configuration.IncludeAllMetadata, worker.ReportProgress);
                    //_systemComparer.RetrieveOrganization(ConnectionType.Source, worker.ReportProgress);
                    SendMessageToStatusBar?.Invoke(this, new StatusBarMessageEventArgs(5, $"Fetching Forms from Source..."));
                    _systemComparer.RetrieveForms(ConnectionType.Source, _configuration.IncludeForms, worker.ReportProgress);

                    SendMessageToStatusBar?.Invoke(this, new StatusBarMessageEventArgs(10, $"Fetching Views from Source..."));
                    _systemComparer.RetrieveViews(ConnectionType.Source, _configuration.IncludeViews, worker.ReportProgress);

                    LogInfo("Start retrieving metadata on Target");
                    SendMessageToStatusBar?.Invoke(this, new StatusBarMessageEventArgs(50, $"Fetching Metadata from Target {(_configuration.IncludeAllMetadata ? "with Attributes" : "without Attributes")}..."));
                    _systemComparer.RetrieveMetadata(ConnectionType.Target, _configuration.IncludeAllMetadata, worker.ReportProgress);
                    //_systemComparer.RetrieveOrganization(ConnectionType.Target, worker.ReportProgress);
                    SendMessageToStatusBar?.Invoke(this, new StatusBarMessageEventArgs(55, $"Fetching Forms from Target..."));
                    _systemComparer.RetrieveForms(ConnectionType.Target, _configuration.IncludeForms, worker.ReportProgress);

                    SendMessageToStatusBar?.Invoke(this, new StatusBarMessageEventArgs(60, $"Fetching Views from Target..."));
                    _systemComparer.RetrieveViews(ConnectionType.Target, _configuration.IncludeViews, worker.ReportProgress);

                    SendMessageToStatusBar?.Invoke(this, new StatusBarMessageEventArgs($"Finished fetching Data!"));
                    args.Result = _systemComparer;
                },
                PostWorkCallBack = (args) =>
                {
                    LogInfo("Postprocessing Metadata");
                    if (args.Error != null)
                    {
                        LogError(args.Error.ToString(), args);
                        MessageBox.Show(args.Error.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }

                    var emds = (Logic.SystemComparer)args.Result;

                    CreateListFromResults(emds);
                },
                ProgressChanged = e => { SetWorkingMessage(e.UserState.ToString()); }
            });
        }
        /// <summary>
        /// Load the Alternate Key info for the selected Entitie
        /// </summary>
        private void LoadSelectedEntityKeys()
        {
            ToggleMainUIControlsEnabled(false);
            var selectedEntities = EntitiesListControl.CheckedEntities;

            WorkAsync(new WorkAsyncInfo {
                Message       = "Retrieving the list of Entities",
                AsyncArgument = selectedEntities,
                IsCancelable  = true,
                MessageWidth  = 340,
                MessageHeight = 150,
                Work          = (w, e) => {
                    var entExpanded = new List <EntityMetadata>();
                    // then reload details for each
                    var count = 0;
                    var total = selectedEntities.Count;

                    // build the list of keys that we want to retrieve
                    var entLogicalNameList = new List <string>();
                    foreach (var ent in selectedEntities)
                    {
                        w.ReportProgress(100 * count++ / total, $"Loading Entities: {ent.LogicalName}");
                        entLogicalNameList.Add(ent.LogicalName);
                    }

                    entExpanded = CrmActions.RetrieveEntity(Service, entLogicalNameList);

                    e.Result = entExpanded;

                    w.ReportProgress(100, $"Loading Entities complete");
                },
                ProgressChanged = e => {
                    SendMessageToStatusBar?.Invoke(this, new StatusBarMessageEventArgs(e.ProgressPercentage, e.UserState.ToString()));
                },
                PostWorkCallBack = e =>
                {
                    _expandedEntities.Clear();
                    _expandedEntities = e.Result as List <EntityMetadata>;

                    // now load up the list view with the keys
                    PopulateKeysListView();

                    ToggleMainUIControlsEnabled(true);
                }
            });
        }
        /// <summary>
        /// Delete items in the collection
        /// </summary>
        /// <param name="rows"></param>
        private void DeleteSiteSettings(EntityCollection rows)
        {
            var execMulti = new ExecuteMultipleRequest()
            {
                Settings = new ExecuteMultipleSettings()
                {
                    ContinueOnError = true,
                    ReturnResponses = true
                },
                Requests = new OrganizationRequestCollection()
            };

            // now make the inserts
            foreach (Entity item in rows.Entities)
            {
                execMulti.Requests.Add(new DeleteRequest()
                {
                    Target = item.ToEntityReference()
                });
            }
            // TODO handle any exec multiple issues
            WorkAsync(
                new WorkAsyncInfo()
            {
                AsyncArgument = execMulti,
                Message       = "Deleting Portal Site Settings Records",
                MessageWidth  = 340,
                MessageHeight = 150,
                Work          = (w, e) =>
                {
                    var req  = e.Argument as ExecuteMultipleRequest;
                    var resp = Service.Execute(req) as ExecuteMultipleResponse;
                    e.Result = resp;
                },
                ProgressChanged = e =>
                {
                    SendMessageToStatusBar?.Invoke(this, new StatusBarMessageEventArgs(e.ProgressPercentage, e.UserState.ToString()));
                },
                PostWorkCallBack = e =>
                {
                    LoadSiteSettings(false);
                }
            }
                );
        }
        private void ProcessArtefacts()
        {
            if (SelectedOperation == PluginOperation.Delete)
            {
                var nUnitsOfWork      = lvCrmArtefacts.CheckedItems.Count;
                var nUnitsOfWorkDone  = 0;
                var percentagePerUnit = 100 / nUnitsOfWork;

                SendMessageToStatusBar?.Invoke(this, new StatusBarMessageEventArgs(nUnitsOfWorkDone, $"Deleting {nUnitsOfWork} artefacts"));
                // Iterate over all artefacts and delete
                foreach (ListViewItem item in lvCrmArtefacts.CheckedItems)
                {
                    var artefact = (IPersonalArtefact)item.Tag;
                    artefact.Container.Delete(artefact);
                    SendMessageToStatusBar?.Invoke(this, new StatusBarMessageEventArgs(Math.Min(100, ++nUnitsOfWork * percentagePerUnit), $"Deleting artefacts"));
                }
            }
            else
            {
                var nUnitsOfWork      = lvCrmArtefacts.CheckedItems.Count * SelectedTargetUsers.Length;
                var nUnitsOfWorkDone  = 0;
                var percentagePerUnit = 100 / nUnitsOfWork;

                SendMessageToStatusBar?.Invoke(this, new StatusBarMessageEventArgs(nUnitsOfWorkDone, $"Processing {nUnitsOfWork} artefacts"));
                // Iterate through all possible artefact-user combinations and process
                foreach (var targetUser in SelectedTargetUsers)
                {
                    foreach (ListViewItem item in lvCrmArtefacts.CheckedItems)
                    {
                        var artefact = (IPersonalArtefact)item.Tag;
                        switch (SelectedOperation)
                        {
                        case PluginOperation.Assign:
                            artefact.Container.Assign(artefact, targetUser);
                            break;

                        case PluginOperation.Duplicate:
                            artefact.Container.Duplicate(artefact, targetUser);
                            break;
                        }
                        SendMessageToStatusBar?.Invoke(this, new StatusBarMessageEventArgs(Math.Min(100, ++nUnitsOfWork * percentagePerUnit), $"Processing artefacts"));
                    }
                }
            }
        }
        /// <summary>
        /// Retrieves templates from the source organization
        /// </summary>
        private void RetrieveTemplates()
        {
            lvTemplates.Items.Clear();

            tsbLoadTemplates.Enabled      = false;
            tsbTransfertTemplates.Enabled = false;
            btnSelectTarget.Enabled       = false;
            Cursor = Cursors.WaitCursor;

            SendMessageToStatusBar?.Invoke(this, new StatusBarMessageEventArgs("Loading templates..."));

            var bw = new BackgroundWorker();

            bw.DoWork += (sender, e) =>
            {
                e.Result = tManager.GetTemplates(Service);
            };
            bw.RunWorkerCompleted += (sender, e) =>
            {
                if (e.Error == null)
                {
                    foreach (var template in (List <Entity>)e.Result)
                    {
                        var item = new ListViewItem();
                        item.Tag  = template;
                        item.Text = template.GetAttributeValue <string>("name");
                        lvTemplates.Items.Add(item);
                    }
                }
                else
                {
                    MessageBox.Show(ParentForm, @"An error has occured while loading templates: " + e.Error.Message, @"Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }

                tsbLoadTemplates.Enabled      = true;
                tsbTransfertTemplates.Enabled = true;
                btnSelectTarget.Enabled       = true;
                Cursor = Cursors.Default;

                SendMessageToStatusBar?.Invoke(this, new StatusBarMessageEventArgs(string.Empty));
            };
            bw.RunWorkerAsync();
        }
示例#19
0
 private void GetEntityCount()
 {
     ShowInfoNotification("Calculation can take a while depending on entity record size, so sit back and relax!", null);
     WorkAsync(new WorkAsyncInfo
     {
         Message = "retrieving Entity Records...",
         Work    = (w, e) =>
         {
             int counter = 0;
             foreach (Model.EntityUsageGridModel elem in _usageManager.Gridlist)
             {
                 counter++;
                 w.ReportProgress((int)Math.Round((double)(100 * counter) / _usageManager.Gridlist.Count), $"Loading {elem.EntityName}...");
                 elem.Count(Service);
             }
             e.Result = _usageManager.Gridlist;
         },
         ProgressChanged = e =>
         {
             SetWorkingMessage(e.UserState.ToString());
             SendMessageToStatusBar?.Invoke(this, new StatusBarMessageEventArgs(e.ProgressPercentage, $"(total: {_usageManager.Gridlist.Count}) Querying data"));
         },
         PostWorkCallBack = args =>
         {
             if (args.Error != null)
             {
                 MessageBox.Show(args.Error.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
             }
             var result = args.Result as List <Model.EntityUsageGridModel>;
             if (result != null)
             {
                 gridEntity.DataSource = new Macchiator.SortableBindingList <EntityUsageGridModel>(result);
                 btnXlsxExport.Enabled = true;
             }
             HideNotification();
             gridEntity.AutoResizeColumns();
         },
         AsyncArgument = null,
         // Progress information panel size
         MessageWidth  = 340,
         MessageHeight = 150
     });
 }
示例#20
0
        private void LoadEntities()
        {
            WorkAsync(new WorkAsyncInfo
            {
                Message       = "Retrieving the list of Entities",
                AsyncArgument = propertyGridConfig.SelectedObject,
                IsCancelable  = true,
                MessageWidth  = 340,
                MessageHeight = 150,
                Work          = (w, e) =>
                {
                    try
                    {
                        w.ReportProgress(0, "Loading Entities from CRM");

                        var config = e.Argument as ConfigurationInfo;

                        e.Result = CrmActions.GetAllEntities(Service, config);

                        w.ReportProgress(100, "Loading Entities from CRM Complete!");
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show("An error occured attetmpting to load the list of Entities:\n" + ex.Message);
                    }
                },
                ProgressChanged = e =>
                {
                    SendMessageToStatusBar?.Invoke(this, new StatusBarMessageEventArgs(e.ProgressPercentage, e.UserState.ToString()));
                },
                PostWorkCallBack = e =>
                {
                    // let them do stuff again
                    ToggleMainControlsEnabled(true);

                    SendMessageToStatusBar?.Invoke(this, new StatusBarMessageEventArgs(0, ""));

                    // launch the results window... get off this worker thread so we can work with the dialog correctly
                    BeginInvoke(new LoadEntitiesCompleteDelegate(LoadEntitiesComplete), new object[] { e.Result as List <EntityMetadata> });
                }
            });
        }
        private void CreateListFromResults(Logic.SystemComparer emds)
        {
            SendMessageToStatusBar?.Invoke(this, new StatusBarMessageEventArgs(0, $"Generating List"));
            comparisonListView.Items.Clear();

            /*OrganizationComparer orgComparer = new OrganizationComparer();
             *      MetadataComparison orgComparison = null;
             *      orgComparison = orgComparer.Compare("Organization", emds._sourceCustomizationRoot.Organizations,
             *          emds._targetCustomizationRoot.Organizations);*/


            if (_configuration.IncludeViews)
            {
                SendMessageToStatusBar?.Invoke(this, new StatusBarMessageEventArgs(0, "Processing Views..."));
                EntityComparer     viewComparer   = new EntityComparer();
                MetadataComparison viewComparison = viewComparer.Compare("Views",
                                                                         emds.SourceCustomizationRoot.Views,
                                                                         emds.TargetCustomizationRoot.Views);
                AddItem(viewComparison, null);
            }

            if (_configuration.IncludeForms)
            {
                SendMessageToStatusBar?.Invoke(this, new StatusBarMessageEventArgs(33, "Processing Forms..."));
                EntityComparer     formComparer   = new EntityComparer();
                MetadataComparison formComparison = formComparer.Compare("Forms",
                                                                         emds.SourceCustomizationRoot.Forms,
                                                                         emds.TargetCustomizationRoot.Forms);
                AddItem(formComparison, null);
            }

            SendMessageToStatusBar?.Invoke(this, new StatusBarMessageEventArgs(66, "Processing Forms..."));
            MetadataComparer   comparer   = new MetadataComparer(_configuration);
            MetadataComparison comparison = comparer.Compare("Entities",
                                                             emds.SourceCustomizationRoot.EntitiesRaw,
                                                             emds.TargetCustomizationRoot.EntitiesRaw);

            AddItem(comparison, null);

            SendMessageToStatusBar?.Invoke(this, new StatusBarMessageEventArgs("List generated!"));
        }
        public void LoadItems()
        {
            ComputeSettings();
            WorkAsync(new WorkAsyncInfo
            {
                Message = "Loading entities...",
                Work    = (bw, evt) =>
                {
                    ecpEntities.LoadEntities(settings);
                    emds = ecpEntities.Metadata;

                    bw.ReportProgress(0, "Loading Web sites");

                    evt.Result = Service.RetrieveMultiple(new QueryExpression("adx_website")
                    {
                        ColumnSet = new ColumnSet(true)
                    }).Entities.Select(record => new Website(record)).ToList();
                },
                PostWorkCallBack = evt =>
                {
                    if (evt.Error != null)
                    {
                        MessageBox.Show(this, $"An error occured: {evt.Error.Message}", "Error", MessageBoxButtons.OK,
                                        MessageBoxIcon.Error);
                        return;
                    }

                    ecpEntities.FillList();
                    wpcWebsiteFilter.Websites = (List <Website>)evt.Result;

                    tsbRetrieveRecords.Enabled = true;
                    tsddSettings.Enabled       = true;
                },
                ProgressChanged = evt =>
                {
                    SetWorkingMessage(evt.UserState.ToString());
                    SendMessageToStatusBar?.Invoke(this, new StatusBarMessageEventArgs(evt.UserState.ToString()));
                }
            });
        }
示例#23
0
        /// <summary>
        /// Load all of the system document templates from the current connection
        /// </summary>
        private void LoadDocumentTemplates(Action onCompleteCallback)
        {
            WorkAsync(new WorkAsyncInfo
            {
                Message = "Retrieving the list of Document Templates",
                Work    = (w, e) =>
                {
                    try
                    {
                        w.ReportProgress(0, "Loading Templates from CRM");
                        e.Result = DocumentTemplateEdit.GetDocumentTemplates(Service);
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.Message);
                    }
                },
                ProgressChanged = e =>
                {
                    SendMessageToStatusBar?.Invoke(this, new StatusBarMessageEventArgs(e.ProgressPercentage, e.UserState.ToString()));
                },
                PostWorkCallBack = e =>
                {
                    var templates = e.Result as List <DocumentTemplateEdit>;

                    // load the templates
                    LoadTemplatesComplete(templates);

                    // now update the UI with the new selection
                    UpdateControlsForSelection();

                    // invoke the callback if passed
                    onCompleteCallback?.Invoke();
                },
                AsyncArgument = null,
                IsCancelable  = true,
                MessageWidth  = 340,
                MessageHeight = 150
            });
        }
        /// <summary>
        /// Populate the Alternate Key details pane
        /// </summary>
        private void PopulateNewKeyControls()
        {
            ToggleNewKeyPaneEnabled(false);
            ToggleMainUIControlsEnabled(false);

            // load the entities into the drop down control
            EntityDropDown.LoadData();

            WorkAsync(new WorkAsyncInfo {
                Message       = "Retrieving Publishers",
                AsyncArgument = null,
                IsCancelable  = true,
                MessageWidth  = 340,
                MessageHeight = 150,
                Work          = (w, e) => {
                    var entLogicalName = e.Argument as string;

                    w.ReportProgress(0, $"Retrieving Publishers");

                    var results = CrmActions.RetrievePublishers(Service);

                    w.ReportProgress(100, $"Retrieving Publishers complete!");

                    e.Result = results;
                },
                ProgressChanged = e => {
                    SendMessageToStatusBar?.Invoke(this, new StatusBarMessageEventArgs(e.ProgressPercentage, e.UserState.ToString()));
                },
                PostWorkCallBack = e => {
                    var pubs = e.Result as List <Entity>;
                    comboBoxPrefixes.Items.Clear();

                    // load the publishers
                    foreach (var pub in pubs)
                    {
                        comboBoxPrefixes.Items.Add(pub.Attributes["customizationprefix"]);
                    }
                }
            });
        }
        private void PaintResults()
        {
            activeList        = results.Peek().Data.Tables[0];
            tslCached.Visible = results.Peek().FromCache;

            List <string> header = new List <string>();

            foreach (Result r in results)
            {
                header.Add(r.Header);
            }
            gbMain.Text = string.Join(" <= ", header);

            dgvMain.DataSource = activeList;

            dgvMain.Columns["Key"].Visible = false;
            dgvMain.RowHeadersWidth        = dgvMain.ColumnHeadersHeight;
            string search = results.Peek().SearchText;

            tsbSearch.Text = "";
            tsbSearch.Text = search;

            if (results.Peek().Data.Tables.Count > 1)
            {
                DataTable det = results.Peek().Data.Tables[1];
                dgvRelationships.DataSource             = det;
                dgvRelationships.Columns["key"].Visible = false;
                dgvRelationships.RowHeadersWidth        = dgvRelationships.ColumnHeadersHeight;
            }
            else
            {
                dgvRelationships.DataSource = null;
            }

            SendMessageToStatusBar?.Invoke(this, new StatusBarMessageEventArgs(string.Format("{0} results loaded", dgvMain.Rows.Count)));
        }
示例#26
0
        public void CreateStepProcess(ListView listView, List <CarfupStep> stepsList, IOrganizationService service)
        {
            var addToSolution = false;
            var itemCount     = listView.CheckedItems.Count;

            if (itemCount < 1)
            {
                MessageBox.Show(@"Make sure you checked at least one step before trying to perform a Copy action.", @"Information", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }

            if (ComparisonMethod.SolutionSpecified)
            {
                var whichDestination = MessageBox.Show(@"Since you have specified a solution, do you want to copy the step to the specified solution?\r\rYes : Custom Solution.\rNo : Default Solution.\rCancel : Abort operation.", @"Which destination do you want?", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question);

                if (whichDestination == DialogResult.Yes)
                {
                    addToSolution = true;
                }
                else if (whichDestination == DialogResult.Cancel)
                {
                    return;
                }
            }

            // Getting list of selected Items
            var stepsGuid = new ListViewItem[itemCount];
            var logAction = (stepsList == StepsCrmSource) ? LogAction.StepCreatedSourceToTarget : LogAction.StepCreatedTargetToSource;

            WorkAsync(new WorkAsyncInfo
            {
                Message = "Creating the step(s) in the environment...",
                Work    = (bw, e) =>
                {
                    Invoke(new Action(() =>
                    {
                        listView.CheckedItems.CopyTo(stepsGuid, 0);
                    }));

                    var i = 1;
                    foreach (var itemView in stepsGuid)
                    {
                        var percentage = (i * 100) / itemCount;
                        SendMessageToStatusBar?.Invoke(this, new StatusBarMessageEventArgs(percentage, $"Creating the step(s) in the environment : {i}/{itemCount}"));
                        var selectedStep = stepsList.FirstOrDefault(x => x.StepName == itemView.Text);
                        var stepCreated  = CreateStep(selectedStep, (stepsList == StepsCrmSource));

                        if (stepCreated == null)
                        {
                            return;
                        }

                        if (addToSolution)
                        {
                            bw.ReportProgress(percentage, $"Adding the new created step to the {SolutionAssemblyPluginStepsName} solution...");

                            service.Execute(new AddSolutionComponentRequest
                            {
                                ComponentId        = stepCreated.Value,
                                ComponentType      = 92,
                                SolutionUniqueName = SolutionAssemblyPluginStepsName
                            });
                        }
                        i++;
                    }
                },
                PostWorkCallBack = e =>
                {
                    if (e.Error != null)
                    {
                        Log.LogData(EventType.Exception, logAction, e.Error);
                        MessageBox.Show(this, e.Error.Message, @"Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        return;
                    }

                    Log.LogData(EventType.Event, logAction);
                    MessageBox.Show($@"Your step(s) were successfully copied to the {(addToSolution ? SolutionAssemblyPluginStepsName : "default")} solution in the {((logAction == LogAction.StepCreatedSourceToTarget) ? "target" : "source")} environment.");
                    labelSourceTargetMatch.Visible = false;
                    labelTargetSourceMatch.Visible = false;
                },
                ProgressChanged = e => { SetWorkingMessage(e.UserState.ToString()); }
            });
        }
示例#27
0
        private void Compare()
        {
            if (ComparisonMethod.RequiresItemSelection &&
                SolutionAssemblyPluginStepsName == null)
            {
                MessageBox.Show($@"Please select a {ComparisonMethod.Name} first.");
                return;
            }

            string[] diffCrmSourceTarget = null;
            string[] diffCrmTargetSource = null;

            StepsCrmSource.Clear();
            StepsCrmTarget.Clear();

            WorkAsync(new WorkAsyncInfo
            {
                Message = $"Comparing the 2 {ComparisonMethod.PluralName.Capitalize()}...",
                Work    = (bw, e) =>
                {
                    SendMessageToStatusBar?.Invoke(this, new StatusBarMessageEventArgs(0, "Fetching steps from source environment..."));
                    StepsCrmSource = ComparisonMethod.GetSteps(SourceService, Settings, SolutionAssemblyPluginStepsName);
                    SendMessageToStatusBar?.Invoke(this, new StatusBarMessageEventArgs(30, "Fetching steps from target environment..."));
                    StepsCrmTarget = ComparisonMethod.GetSteps(TargetService, Settings, SolutionAssemblyPluginStepsName);
                    foreach (var step in StepsCrmTarget)
                    {
                        step.Environment = "Target";
                    }

                    SendMessageToStatusBar?.Invoke(this, new StatusBarMessageEventArgs(60, "Comparing steps..."));

                    Comparer.Compare(StepsCrmSource, StepsCrmTarget);
                    SendMessageToStatusBar?.Invoke(this, new StatusBarMessageEventArgs(90, "Finding Differences..."));
                    diffCrmSourceTarget = StepsCrmSource.Select(x => x.StepName).Except(StepsCrmTarget.Select(x => x.StepName)).ToArray();
                    diffCrmTargetSource = StepsCrmTarget.Select(x => x.StepName).Except(StepsCrmSource.Select(x => x.StepName)).ToArray();
                    SendMessageToStatusBar?.Invoke(this, new StatusBarMessageEventArgs(100, "Done!"));
                },
                PostWorkCallBack = e =>
                {
                    if (e.Error != null)
                    {
                        Log.LogData(EventType.Exception, ComparisonMethod.LogActionOnCompare, e.Error);
                        MessageBox.Show(this, e.Error.Message, @"Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        toolStripButtonExport.Enabled = false;
                        return;
                    }

                    toolStripButtonExport.Enabled = true;

                    if (diffCrmSourceTarget.Length == 0)
                    {
                        listViewSourceTarget.Items.Clear();
                        labelSourceTargetMatch.Visible = true;
                    }
                    else // there are steps in source but not target
                    {
                        labelSourceTargetMatch.Visible = false;
                        listViewSourceTarget.Visible   = true;
                        FillListViewItems(listViewSourceTarget, StepsCrmSource, diffCrmSourceTarget);
                    }

                    if (diffCrmTargetSource.Count() == 0)
                    {
                        listViewTargetSource.Items.Clear();
                        labelTargetSourceMatch.Visible = true;
                    }
                    else // there are steps in source but not target
                    {
                        labelTargetSourceMatch.Visible = false;
                        listViewTargetSource.Visible   = true;
                        FillListViewItems(listViewTargetSource, StepsCrmTarget, diffCrmTargetSource);
                    }

                    Log.LogData(EventType.Event, ComparisonMethod.LogActionOnCompare);
                },
                ProgressChanged = e =>
                {
                    SetWorkingMessage(e.UserState.ToString());
                }
            });
        }
示例#28
0
        /// <summary>
        /// Based on the current selection, generate the templates
        /// </summary>
        /// <param name="generateCheckedItems">Flag indicating whether to generate the checked items or the single selected item</param>
        private void GenerateTemplates(bool generateCheckedItems = false)
        {
            ToggleMainControlsEnabled(false);

            var entitiesList = new List <string>();

            // generate checked vs selected items.
            if (generateCheckedItems)
            {
                foreach (ListViewItem item in listViewEntities.CheckedItems)
                {
                    entitiesList.Add(item.SubItems["Name"].Text);
                }
            }
            else
            {
                var selItem = listViewEntities.SelectedItems[0];
                entitiesList.Add(selItem.SubItems["Name"].Text);
            }

            WorkAsync(new WorkAsyncInfo
            {
                Message       = "Generating the script template for selected entities",
                AsyncArgument = new List <object>()
                {
                    entitiesList, propertyGridConfig.SelectedObject
                },
                IsCancelable  = true,
                MessageWidth  = 340,
                MessageHeight = 150,
                Work          = (w, e) =>
                {
                    Xrm2TypeScriptGenerator xrm2ts = null;
                    try
                    {
                        var args      = e.Argument as List <object>;
                        var namesList = args[0] as List <string>;
                        var config    = args[1] as ConfigurationInfo;

                        // collect all of the entity metadata items with the attribubte metadata
                        var selectedEntities = new List <EntityMetadata>();

                        var counter = 0;
                        var total   = namesList.Count;
                        //foreach selected entity in the listbox
                        foreach (string logicalName in namesList)
                        {
                            w.ReportProgress((counter++ / total) * 100, "Loading Entity: " + logicalName);
                            selectedEntities.Add(CrmActions.RetrieveEntityAttributeMeta(Service, config, logicalName));
                        }

                        w.ReportProgress(100, "Loading Entities Complete");

                        // generate the list of selected entities
                        xrm2ts = new Xrm2TypeScriptGenerator(config, selectedEntities);

                        // TODO move the type into the script types
                        xrm2ts.GenerateAllClassTemplates();

                        e.Result = xrm2ts;
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show("An error occurred attempting to generate the template for your selection:\n" + ex.Message + "\n Logging results:\n" + xrm2ts.Logger.ToString());
                    }
                },
                ProgressChanged = e =>
                {
                    SendMessageToStatusBar?.Invoke(this, new StatusBarMessageEventArgs(e.ProgressPercentage, e.UserState.ToString()));
                },
                PostWorkCallBack = e =>
                {
                    // let them do stuff again
                    ToggleMainControlsEnabled(true);

                    // launch the results window... get off this worker thread so we can work with the dialog correctly
                    BeginInvoke(new ProcessingCompleteDelegate(ProcessingComplete), new object[] { e.Result as Xrm2TypeScriptGenerator });
                }
            });
        }
        private void TransferData(EntityCollection ec, IOrganizationService service)
        {
            // References to websites
            var webSitesRefId = ec.Entities.SelectMany(e => e.Attributes)
                                .Where(a => a.Value is EntityReference reference && reference.LogicalName == "adx_website")
                                .Select(a => ((EntityReference)a.Value).Id)
                                .Distinct()
                                .ToList();

            // Websites included in records to process
            var webSitesIds = ec.Entities.Where(e => e.LogicalName == "adx_website")
                              .Select(e => e.Id)
                              .ToList();

            // If some references are not found in websites included in records
            // to process, ask the user to map to the appropriate website
            if (!webSitesRefId.All(id => webSitesIds.Contains(id)))
            {
                try
                {
                    var targetWebSites = service.RetrieveMultiple(new QueryExpression("adx_website")
                    {
                        ColumnSet = new ColumnSet("adx_name")
                    }).Entities;

                    if (!webSitesRefId.All(id => targetWebSites.Select(w => w.Id).Contains(id)))
                    {
                        var wsmDialog = new WebSiteMapper(ec, targetWebSites.Select(t => new Website(t)).ToList());
                        if (wsmDialog.ShowDialog() == DialogResult.Cancel)
                        {
                            return;
                        }
                    }
                }
                catch (FaultException <OrganizationServiceFault> error)
                {
                    if (error.Detail.ErrorCode == -2147217150)
                    {
                        MessageBox.Show(this,
                                        @"The target environment does not seem to have Portals solutions installed!",
                                        @"Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                    else
                    {
                        MessageBox.Show(this,
                                        $@"An unknown error occured when searching for websites: {error.Detail.Message}",
                                        @"Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                    pnlImport.SendToBack();
                    tsMain.Enabled = true;
                    return;
                }
            }

            var pluginCheck     = ec.Entities.Any(e => e.LogicalName == "adx_webpage");
            var javascriptCheck =
                ec.Entities.Any(e =>
                                e.LogicalName == "annotation" &&
                                (e.GetAttributeValue <string>("filename")?.ToLower().EndsWith(".js") ?? false)) &&
                nManager.HasJsRestriction;
            var webFileCleaning = ec.Entities.Any(e =>
                                                  e.LogicalName == "annotation" &&
                                                  e.GetAttributeValue <EntityReference>("objectid")?.LogicalName == "adx_webfile");

            if (pluginCheck || javascriptCheck)
            {
                var dialog = new PreImportWarningDialog(pluginCheck, javascriptCheck, webFileCleaning);
                var result = dialog.ShowDialog(this);
                if (result == DialogResult.Cancel)
                {
                    return;
                }

                iSettings.DeactivateWebPagePlugins        = true;
                iSettings.RemoveJavaScriptFileRestriction = true;
                iSettings.CleanWebFiles = dialog.CleanWebFiles;
            }

            var lm = new LogManager(GetType());

            if (File.Exists(lm.FilePath))
            {
                if (MessageBox.Show(this, @"A log file already exists. Would you like to create a new log file?", @"Question", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                {
                    File.Copy(lm.FilePath, $"{lm.FilePath.Substring(0, lm.FilePath.Length - 4)}-{DateTime.Now:yyyyMMdd_HHmmss}.txt", true);
                    File.Delete(lm.FilePath);
                }
            }

            btnCancel.Visible     = true;
            btnImport.Enabled     = false;
            pnlImportMain.Visible = true;
            pbImport.IsOnError    = false;
            lvProgress.Items.Clear();

            var worker = new BackgroundWorker
            {
                WorkerReportsProgress      = true,
                WorkerSupportsCancellation = true
            };

            worker.DoWork += (s, evt) =>
            {
                importWorker = (BackgroundWorker)s;

                if (emds.Count == 0)
                {
                    AddTile("Retrieve metadata", "We need entities metadata to process your records");

                    emds = MetadataManager.GetEntitiesList(service);

                    CompleteTile();
                }

                if (iSettings.DeactivateWebPagePlugins)
                {
                    AddTile("Disable plugins", "We need to disable web page plugins to ensure we don't create duplicates");

                    logger.LogInfo("Deactivating Webpage plugins steps");

                    pManager = new PluginManager(service);
                    pManager.DeactivateWebpagePlugins();

                    CompleteTile();

                    logger.LogInfo("Webpage plugins steps deactivated");
                }

                if (iSettings.RemoveJavaScriptFileRestriction && nManager.HasJsRestriction)
                {
                    AddTile("Remove file restriction", "We need to authorize JavaScript file type to create Web file correctly");

                    logger.LogInfo("Removing JavaScript file restriction");

                    nManager.RemoveRestriction();

                    // Wait 2 seconds to be sure the settings is updated
                    Thread.Sleep(2000);

                    CompleteTile();

                    logger.LogInfo("JavaScript file restriction removed");
                }

                AddTile("Process records", "Records are processed in three phases : one phase without lookup being populated. A second phase with lookup being populated. This ensure all relationships between records can be created on the second phase. And a third phase to deactivate records that need it.");

                var rm = new RecordManager(service);
                evt.Cancel = rm.ProcessRecords((EntityCollection)evt.Argument, emds, ConnectionDetail.OrganizationMajorVersion, importWorker, iSettings);

                if (evt.Cancel)
                {
                    CancelTile();
                }
                else
                {
                    CompleteTile();
                }

                if (iSettings.DeactivateWebPagePlugins)
                {
                    AddTile("Enable plugins", "We are enabling web page plugins so that your portal work smoothly");
                    logger.LogInfo("Reactivating Webpage plugins steps");

                    pManager.ActivateWebpagePlugins();

                    logger.LogInfo("Webpage plugins steps activated");
                    CompleteTile();
                }

                if (iSettings.RemoveJavaScriptFileRestriction && nManager.HasJsRestriction)
                {
                    AddTile("Add file restriction", "We are adding back restriction for JavaScript files.");
                    logger.LogInfo("Adding back JavaScript file restriction");

                    importWorker.ReportProgress(0, "Adding back JavaScript file restriction...");
                    nManager.AddRestriction();

                    logger.LogInfo("JavaScript file restriction added back");
                    CompleteTile();
                }
            };
            worker.RunWorkerCompleted += (s, evt) =>
            {
                llOpenLogFile.Visible  = true;
                btnImportClose.Enabled = true;
                btnImport.Enabled      = true;
                btnCancel.Visible      = false;

                if (evt.Cancelled)
                {
                    CancelTile();
                    lblProgress.Text = @"Import was canceled!";
                    return;
                }

                if (evt.Error != null)
                {
                    CancelTile();

                    logger.LogError(evt.Error.ToString());

                    MessageBox.Show(this, $@"An error occured: {evt.Error.Message}", @"Error", MessageBoxButtons.OK,
                                    MessageBoxIcon.Error);
                    return;
                }

                SendMessageToStatusBar?.Invoke(this, new StatusBarMessageEventArgs(string.Empty));
                lblProgress.Text = @"Records imported!";

                if (pbImport.IsOnError)
                {
                    MessageBox.Show(this, @"Import complete with errors

Please review the logs", @"Information", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                }
                else
                {
                    MessageBox.Show(this, @"Import complete", @"Success", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
            };
            worker.ProgressChanged += (s, evt) =>
            {
                if (evt.UserState is string)
                {
                    lblProgress.Text = evt.UserState.ToString();
                    logger.LogInfo(evt.UserState.ToString());

                    SendMessageToStatusBar?.Invoke(this, new StatusBarMessageEventArgs(evt.UserState.ToString()));
                }
                else
                {
                    if (evt.UserState is ImportProgress progress)
                    {
                        foreach (var ep in progress.Entities)
                        {
                            var item = lvProgress.Items.Cast <ListViewItem>().FirstOrDefault(i => i.Tag.ToString() == ep.LogicalName);
                            if (item == null)
                            {
                                item = new ListViewItem($"{ep.Entity} ({ep.Count})")
                                {
                                    Tag = ep.LogicalName
                                };
                                item.SubItems.Add(ep.SuccessFirstPhase.ToString());
                                item.SubItems.Add(ep.ErrorFirstPhase.ToString());
                                item.SubItems.AddRange(new[] { "", "", "", "" });

                                if (ep.SuccessSecondPhase.HasValue || ep.ErrorSecondPhase.HasValue)
                                {
                                    item.SubItems[3].Text = (ep.SuccessSecondPhase ?? 0).ToString();
                                    item.SubItems[4].Text = (ep.ErrorSecondPhase ?? 0).ToString();
                                }

                                if (ep.SuccessSetStatePhase.HasValue || ep.ErrorSetState.HasValue)
                                {
                                    item.SubItems[5].Text = (ep.SuccessSetStatePhase ?? 0).ToString();
                                    item.SubItems[6].Text = (ep.ErrorSetState ?? 0).ToString();
                                }

                                lvProgress.Items.Add(item);
                            }
                            else
                            {
                                item.SubItems[1].Text = ep.SuccessFirstPhase.ToString();
                                item.SubItems[2].Text = ep.ErrorFirstPhase.ToString();

                                if (ep.SuccessSecondPhase.HasValue || ep.ErrorSecondPhase.HasValue)
                                {
                                    item.SubItems[3].Text = (ep.SuccessSecondPhase ?? 0).ToString();
                                    item.SubItems[4].Text = (ep.ErrorSecondPhase ?? 0).ToString();
                                }

                                if (ep.SuccessSetStatePhase.HasValue || ep.ErrorSetState.HasValue)
                                {
                                    item.SubItems[5].Text = (ep.SuccessSetStatePhase ?? 0).ToString();
                                    item.SubItems[6].Text = (ep.ErrorSetState ?? 0).ToString();
                                }
                            }

                            item.ForeColor = ep.ErrorFirstPhase > 0 || ep.ErrorSecondPhase > 0 || ep.ErrorSetState > 0
                                ? Color.Red
                                : Color.Green;

                            if (ep.ErrorFirstPhase > 0 || ep.ErrorSecondPhase > 0 || ep.ErrorSetState > 0)
                            {
                                pbImport.IsOnError = true;
                            }

                            pbImport.Value = progress.Entities.Sum(ent => ent.Processed) * 100 / progress.Count;
                        }
                    }
                }
            };
            worker.RunWorkerAsync(ec);
        }
        private void ExportData(bool isFileExport)
        {
            ComputeSettings();

            var ec = new EntityCollection();

            // Gathering records to export
            foreach (TabPage tp in tabCtrl.TabPages)
            {
                var rlc = (RecordsListerControl)tp.Controls[0];
                ec.Entities.AddRange(rlc.Records);
            }

            if (ec.Entities.Count == 0)
            {
                MessageBox.Show(this, @"No record selected!", @"Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }

            foreach (var record in ec.Entities)
            {
                var emd = settings.AllEntities.First(ent => ent.LogicalName == record.LogicalName);
                if (!(emd.IsIntersect ?? false))
                {
                    var validAttributes = emd.Attributes
                                          .Where(a => (a.IsValidForCreate ?? false) || (a.IsValidForUpdate ?? false))
                                          .Select(a => a.LogicalName)
                                          .ToArray();

                    for (int i = record.Attributes.Count - 1; i >= 0; i--)
                    {
                        if (!validAttributes.Contains(record.Attributes.ElementAt(i).Key))
                        {
                            record.Attributes.Remove(record.Attributes.ElementAt(i));
                        }
                        else
                        {
                            if (record[record.Attributes.ElementAt(i).Key] is EntityReference er &&
                                er.LogicalName == "contact")
                            {
                                record.Attributes.Remove(record.Attributes.ElementAt(i));
                            }
                        }
                    }

                    foreach (var va in validAttributes)
                    {
                        //add any null attributes to force them to update to null.
                        if (!record.Contains(va))
                        {
                            record[va] = null;
                        }
                    }
                }
            }

            pnlProgressTiles.Controls.Clear();

            WorkAsync(new WorkAsyncInfo
            {
                Message       = "",
                AsyncArgument = ec,
                Work          = (bw, evt) =>
                {
                    var list = (EntityCollection)evt.Argument;

                    var webFiles = list.Entities.Where(ent => ent.LogicalName == "adx_webfile").ToList();
                    if (webFiles.Any())
                    {
                        if (isFileExport)
                        {
                            bw.ReportProgress(0, "Retrieving web files annotation records...");
                        }
                        else
                        {
                            Invoke(new Action(() =>
                            {
                                pnlImportMain.Visible = true;
                                pnlImport.BringToFront();
                            }));
                            AddTile("Retrieve notes", "We need to retrieve notes associated to the web files you want to transfer");
                        }

                        // Force service to source Service before retrieving data
                        rManager.SetService(Service);
                        var records = rManager.RetrieveWebfileAnnotations(webFiles.Select(w => w.Id).ToList());
                        foreach (var record in records)
                        {
                            ec.Entities.Insert(0, record);
                        }

                        CompleteTile();
                    }

                    evt.Result = list;
                },
                PostWorkCallBack = evt =>
                {
                    SendMessageToStatusBar?.Invoke(this, new StatusBarMessageEventArgs(string.Empty));

                    if (evt.Error != null)
                    {
                        CancelTile();
                        MessageBox.Show(this, $@"An error occured: {evt.Error.Message}", @"Error", MessageBoxButtons.OK,
                                        MessageBoxIcon.Error);
                        return;
                    }

                    var list = (EntityCollection)evt.Result;

                    if (isFileExport)
                    {
                        ExportToDisk(list);
                    }
                    else
                    {
                        lblImportHeader.Text = @"Portal Records Transfer";
                        TransferData(list, targetService);
                    }
                },
                ProgressChanged = evt =>
                {
                    SetWorkingMessage(evt.UserState.ToString());
                    SendMessageToStatusBar?.Invoke(this, new StatusBarMessageEventArgs(evt.UserState.ToString()));
                }
            });
        }