/// <summary>
        /// Starts the with source record identification.
        /// </summary>
        /// <param name="sourceRecordIdentification">The source record identification.</param>
        /// <param name="destRecordIdentification">The dest record identification.</param>
        /// <param name="_parameters">The parameters.</param>
        /// <returns></returns>
        public bool StartWithSourceRecordIdentification(string sourceRecordIdentification, string destRecordIdentification, Dictionary <string, object> _parameters)
        {
            if (this.running)
            {
                return(false);
            }

            this.running        = true;
            this.parameters     = _parameters;
            this.replacedFilter = this.TemplateFilter.FilterByApplyingValueDictionaryDefaults(this.parameters, true);
            UPCRMRecord destinationRootRecord = new UPCRMRecord(destRecordIdentification);
            int         count = this.replacedFilter.RootTable.NumberOfSubTables;

            this.recordArray = new List <UPCRMRecord>();
            this.stepQueue   = new List <UPRecordCopyStep>();
            for (int i = 0; i < count; i++)
            {
                UPConfigQueryTable currentTable = this.replacedFilter.RootTable.SubTableAtIndex(i);
                UPRecordCopyStep   recordStep   = new UPRecordCopyStep();
                recordStep.SourceRecordIdentification = sourceRecordIdentification;
                recordStep.QueryTable        = currentTable;
                recordStep.DestinationRecord = destinationRootRecord;
                this.ConfigForStepFromQueryTable(recordStep, currentTable);
                this.stepQueue.Add(recordStep);
            }

            this.ExecuteNextStep();
            return(true);
        }
        private void ConfigForStepFromQueryTable(UPRecordCopyStep recordCopyStep, UPConfigQueryTable queryTable)
        {
            UPConfigQueryCondition sourceConfigNameCondition = queryTable.PropertyConditions.ValueOrDefault("SourceConfig");
            string sourceConfigName = null;

            if (sourceConfigNameCondition != null && sourceConfigNameCondition.FieldValues.Count > 0)
            {
                sourceConfigName = sourceConfigNameCondition.FieldValues[0] as string;
            }

            bool skipSearchAndList = false;

            if (string.IsNullOrEmpty(sourceConfigName))
            {
                sourceConfigName  = queryTable.InfoAreaId;
                skipSearchAndList = true;
            }

            if (!skipSearchAndList)
            {
                recordCopyStep.SearchAndListConfiguration = this.configStore.SearchAndListByName(sourceConfigName);
            }

            if (recordCopyStep.SearchAndListConfiguration == null)
            {
                recordCopyStep.FieldControl = this.configStore.FieldControlByNameFromGroup("Edit", sourceConfigName) ??
                                              this.configStore.FieldControlByNameFromGroup("List", sourceConfigName);
            }
            else
            {
                recordCopyStep.FieldControl = this.configStore.FieldControlByNameFromGroup("List", recordCopyStep.SearchAndListConfiguration.FieldGroupName);
            }
        }
        /// <summary>
        /// Starts the with source record identification.
        /// </summary>
        /// <param name="recordIdentification">The record identification.</param>
        /// <param name="_parameters">The parameters.</param>
        /// <returns></returns>
        public bool StartWithSourceRecordIdentification(string recordIdentification, Dictionary <string, object> _parameters)
        {
            if (this.running)
            {
                return(false);
            }

            this.running        = true;
            this.parameters     = _parameters;
            this.replacedFilter = this.TemplateFilter.FilterByApplyingValueDictionaryDefaults(this.parameters, true);
            UPRecordCopyStep recordStep = new UPRecordCopyStep();

            this.recordArray = new List <UPCRMRecord>();
            recordStep.SourceRecordIdentification = recordIdentification;
            recordStep.QueryTable = this.replacedFilter.RootTable;
            this.ConfigForStepFromQueryTable(recordStep, recordStep.QueryTable);
            this.stepQueue = new List <UPRecordCopyStep> {
                recordStep
            };
            this.ExecuteNextStep();
            return(true);
        }
        private void ExecuteNextStep()
        {
            if (this.TheDelegate == null)
            {
                return;
            }
            else if (this.stepQueue.Count == 0)
            {
                this.FinishWithError(null);
                return;
            }

            UPRecordCopyStep currentStep = this.stepQueue[0];

            if (currentStep.SearchAndListConfiguration != null)
            {
                this.crmQuery = new UPContainerMetaInfo(currentStep.SearchAndListConfiguration, this.parameters);
            }
            else
            {
                this.crmQuery = new UPContainerMetaInfo(currentStep.FieldControl);
            }

            if (this.crmQuery == null)
            {
                this.stepQueue.RemoveAt(0);
                this.ExecuteNextStep();
                return;
            }

            this.crmQuery.SetLinkRecordIdentification(currentStep.SourceRecordIdentification, currentStep.QueryTable.LinkId);
            if (this.crmQuery.Find(this.RequestOption, this) == null)
            {
                this.FinishWithError(new Exception("RecordCopy: could not start search operation"));
                return;
            }
        }
        private void ProcessResult(UPCRMResult result)
        {
            UPRecordCopyStep currentStep = this.stepQueue[0];

            this.stepQueue.RemoveAt(0);
            UPConfigQueryTable queryTable = currentStep.QueryTable;
            int count            = result.RowCount;
            int resultTableCount = result.NumberOfResultTables;
            UPContainerInfoAreaMetaInfo copyResultInfoArea = null;

            if (queryTable.InfoAreaId == currentStep.FieldControl.InfoAreaId)
            {
                copyResultInfoArea = result.MetaInfo.ResultInfoAreaMetaInfoAtIndex(0);
            }

            for (int i = 0; i < count; i++)
            {
                UPCRMResultRow row    = (UPCRMResultRow)result.ResultRowAtIndex(i);
                UPCRMRecord    record = new UPCRMRecord(queryTable.InfoAreaId);
                if (currentStep.DestinationRecord != null)
                {
                    record.AddLink(new UPCRMLink(currentStep.DestinationRecord, queryTable.LinkId));
                }

                for (int j = 1; j < resultTableCount; j++)
                {
                    string linkRecordIdentification = row.RecordIdentificationAtIndex(j);
                    if (string.IsNullOrEmpty(linkRecordIdentification) && !result.IsServerResult)
                    {
                        UPContainerInfoAreaMetaInfo resultInfoArea = result.MetaInfo.ResultInfoAreaMetaInfoAtIndex(j);
                        UPCRMLinkReader             linkReader     = new UPCRMLinkReader(StringExtensions.InfoAreaIdRecordId(currentStep.FieldControl.InfoAreaId, row.RootRecordId),
                                                                                         $"{resultInfoArea.InfoAreaId}:{resultInfoArea.LinkId}", null);
                        linkRecordIdentification = linkReader.RequestLinkRecordOffline();
                    }

                    int linkId = -1;
                    if (linkRecordIdentification?.Length > 8)
                    {
                        if (currentStep.DestinationRecord == null || queryTable.LinkId != linkId ||
                            linkRecordIdentification.InfoAreaId() != currentStep.DestinationRecord.InfoAreaId)
                        {
                            record.AddLink(new UPCRMLink(linkRecordIdentification, linkId));
                        }
                    }
                }

                Dictionary <string, object> fieldsWithFunctions = row.ValuesWithFunctions();
                UPConfigQueryTable          replacedTable       = queryTable.QueryTableByApplyingValueDictionary(fieldsWithFunctions);
                if (copyResultInfoArea != null)
                {
                    foreach (UPContainerFieldMetaInfo field in copyResultInfoArea.Fields)
                    {
                        string val = row.RawValueAtIndex(field.PositionInResult);
                        if (!string.IsNullOrEmpty(val))
                        {
                            record.AddValue(new UPCRMFieldValue(val, field.InfoAreaId, field.FieldId));
                        }
                    }
                }

                if (replacedTable != null)
                {
                    record.ApplyValuesFromTemplateFilter(replacedTable, true);
                }

                int numberOfSubTables = queryTable.NumberOfSubTables;
                if (numberOfSubTables > 0)
                {
                    for (int k = 0; k < numberOfSubTables; k++)
                    {
                        UPRecordCopyStep subStep = new UPRecordCopyStep();
                        subStep.QueryTable = queryTable.SubTableAtIndex(k);
                        subStep.SourceRecordIdentification = row.RootRecordIdentification;
                        subStep.DestinationRecord          = record;
                        this.ConfigForStepFromQueryTable(subStep, subStep.QueryTable);
                        this.stepQueue.Add(subStep);
                    }
                }

                this.recordArray.Add(record);
            }

            this.ExecuteNextStep();
        }