internal void RegisterStageConfigSteps(AutoNumbering preConfig, AutoNumbering postConfig)
        {
            var types = (from typeQ in xrmContext.PluginTypeSet
                         where typeQ.Name == "Yagasoft.AutoNumbering.Plugins.Target.Plugins.PreCreateTargetAutoNum" ||
                         typeQ.Name == "Yagasoft.AutoNumbering.Plugins.Target.Plugins.PostCreateTargetAutoNum"
                         select new PluginType
            {
                PluginTypeId = typeQ.PluginTypeId,
                Name = typeQ.Name
            }).ToList();

            var entityName = (postConfig ?? preConfig)?.EntityLogicalName_ldv_EntityLogicalName;
            var id         = (postConfig ?? preConfig)?.UniqueID;

            entityName.RequireNotEmpty("Entity Name");
            id.RequireNotEmpty("Unique ID");

            var createMessage = GetMessage(entityName, "Create");

            if (preConfig != null)
            {
                foreach (var type in types)
                {
                    createMessage.PluginTypeId = type.PluginTypeId.GetValueOrDefault();
                    DeleteExistingSteps(createMessage, id);
                }
            }

            var stage = postConfig?.AutoregisterStepStage;

            if (stage == null)
            {
                log.Log("No stage defined. Exiting ...");
                return;
            }

            var stageType = types.FirstOrDefault(t =>
                                                 stage == AutoNumbering.AutoregisterStepStageEnum.Preoperation
                                        ? t.Name.Contains("PreCreateTargetAutoNum")
                                        : t.Name.Contains("PostCreateTargetAutoNum"));

            if (stageType == null)
            {
                throw new InvalidPluginExecutionException($"Couldn't find Auto-numbering plugin type for stage '{stage}'.");
            }

            createMessage.PluginTypeId   = stageType.PluginTypeId.GetValueOrDefault();
            createMessage.TypeName       = stageType.Name;
            createMessage.ExecutionStage = stage == AutoNumbering.AutoregisterStepStageEnum.Preoperation
                                ? SdkMessageProcessingStep.ExecutionStageEnum.Preoperation
                                : SdkMessageProcessingStep.ExecutionStageEnum.Postoperation;

            CreateStep(createMessage, entityName, 900, id);
        }
 internal AutoNumberingEngine(IOrganizationService service, CrmLog log,
                              AutoNumbering autoNumberConfig, Entity target, Entity image, string orgId,
                              IEnumerable <string> inputParams = null)
 {
     this.log              = log;
     this.service          = service;
     this.orgId            = orgId;
     this.autoNumberConfig = autoNumberConfig;
     isInlineConfig        = autoNumberConfig.Id == Guid.Empty;
     this.target           = target;
     this.image            = image;
     this.inputParams      = inputParams;
 }
        internal Result GenerateAndUpdateRecord(bool useService = true, bool isUpdate = false, bool isBackLogged = false)
        {
            var autoNumberConfigId = autoNumberConfig.Id;

            if (autoNumberConfig.FormatString == null)
            {
                throw new InvalidPluginExecutionException("Couldn't find a format string in the auto-numbering configuration.");
            }

            var updatedAutoNumbering =
                new AutoNumbering
            {
                Id = autoNumberConfigId
            };

            // generate a string, and make sure it's unique
            var field  = autoNumberConfig.FieldLogicalName?.Trim();
            var result = GenerateUniqueString(isUpdate, updatedAutoNumbering, field);

            log.Log($"Final auto-number: {result}");

            // if target and field exist, then user wants to update the record
            if (target != null && field != null)
            {
                log.Log($"Adding generated number: '{result.GeneratedString}', to field: '{field}' ...");

                if (useService)
                {
                    var updatedTarget =
                        new Entity(target.LogicalName)
                    {
                        Id      = target.Id,
                        [field] = result.GeneratedString
                    };
                    service.Update(updatedTarget);
                }
                else
                {
                    target[field] = result.GeneratedString;
                }
            }

            if (!isInlineConfig && !isBackLogged)
            {
                log.Log($"Updating auto-numbering with index {updatedAutoNumbering.CurrentIndex} ...");
                // set the new dates and index in the auto-numbering record
                service.Update(updatedAutoNumbering);
            }

            return(result);
        }
        private Result GenerateUniqueString(bool isUpdate, AutoNumbering updatedAutoNumbering, string field = null)
        {
            var    generatedString = "";
            bool   isUnique;
            var    iterations = 1;
            Result result;

            if (autoNumberConfig.ValidateUniqueString != false)
            {
                if (field == null)
                {
                    throw new InvalidPluginExecutionException(
                              "To generate a unique string, a target field must be specified in the config record.");
                }

                if (target == null)
                {
                    throw new InvalidPluginExecutionException(
                              "To generate a unique string, a target must be passed as a parameter to the execution.");
                }
            }

            do
            {
                if (iterations > 10)
                {
                    throw new InvalidPluginExecutionException($"Couldn't generate a unique random string => \"{generatedString}\"");
                }

                result          = GenerateString(isUpdate, updatedAutoNumbering);
                generatedString = result.GeneratedString;
                log.Log($"Generated string: {generatedString}", LogLevel.Debug);

                isUnique = autoNumberConfig.ValidateUniqueString != false &&
                           field != null && target != null &&
                           new OrganizationServiceContext(service)
                           .CreateQuery(target.LogicalName)
                           .Where(targetQ => (string)targetQ[field] == generatedString)
                           .Select(targetQ => targetQ[field])
                           .ToList().Count <= 0;

                iterations++;
            }while (autoNumberConfig.ValidateUniqueString != false && !isUnique);

            log.Log($"Accepted generated string: {generatedString}");

            return(result);
        }
예제 #5
0
        /// <summary>
        /// A plug-in that creates a follow-up task activity when a new account is created.
        /// </summary>
        /// <remarks>Register this plug-in on the Create message, account entity,
        /// and asynchronous mode.
        /// </remarks>
        public void Execute(IServiceProvider serviceProvider)
        {
            //Extract the tracing service for use in debugging sandboxed plug-ins.
            ITracingService tracingService =
                (ITracingService)serviceProvider.GetService(typeof(ITracingService));

            // Obtain the execution context from the service provider.
            IPluginExecutionContext context = (IPluginExecutionContext)
                                              serviceProvider.GetService(typeof(IPluginExecutionContext));
            IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
            var service = serviceFactory.CreateOrganizationService(context.UserId);

            // The InputParameters collection contains all the data passed in the message request.
            if (context.InputParameters.Contains("Target") &&
                context.InputParameters["Target"] is Entity)
            {
                // Obtain the target entity from the input parameters.
                Entity entity = (Entity)context.InputParameters["Target"];

                if (entity.LogicalName != "gcbase_client")
                {
                    return;
                }

                //FaultException ex1 = new FaultException();
                //throw new InvalidPluginExecutionException("test", ex1);

                AutoNumbering autoNumbering = new AutoNumbering(entity, service);
                String        clientId      = autoNumbering.getAutoNumber();

                try
                {
                    entity["gcbase_name"] = clientId;
                }

                catch (FaultException <OrganizationServiceFault> ex)
                {
                    throw new InvalidPluginExecutionException("An error occurred in the PreClientCreate plug-in.", ex);
                }

                catch (Exception ex)
                {
                    tracingService.Trace("FollowupPlugin: {0}", ex.ToString());
                    throw;
                }
            }
        }
        private int ProcessIndex(Match match, bool isReset, int resetValue, bool isUpdate, AutoNumbering updatedAutoNumbering)
        {
            var fieldName              = match.Groups[1].Value;
            var fieldValue             = match.Groups[2].Value;
            var isDefaultIndex         = !fieldName.IsNotEmpty();
            var currentIndex           = 0;
            AutoNumberingStream stream = null;

            if (isDefaultIndex)
            {
                log.Log("Using default index.");
                currentIndex = autoNumberConfig.CurrentIndex.GetValueOrDefault();
            }
            else if (match.Success)
            {
                fieldValue = fieldValue.IsNotEmpty()
                                        ? fieldValue
                                        : Libraries.Common.CrmHelpers.GetAttributeStringValue(image.GetAttributeValue <object>(fieldName));
                log.Log($"Parsing stream '{match.Value}' ...");
                log.Log($"Field name: {fieldName}");
                log.Log($"Field value: {fieldValue}");

                log.Log($"Retrieving stream ...");
                stream =
                    (from s in new XrmServiceContext(service)
                {
                    MergeOption = MergeOption.NoTracking
                }.AutoNumberingStreamSet
                     where s.FieldName == fieldName && s.FieldValue == fieldValue &&
                     s.AutoNumberingConfig == autoNumberConfig.Id
                     select new AutoNumberingStream
                {
                    Id = s.Id,
                    CurrentIndex = s.CurrentIndex
                }).FirstOrDefault();

                if (stream == null)
                {
                    log.Log($"Couldn't find stream.");
                    stream =
                        new AutoNumberingStream
                    {
                        CurrentIndex        = 0,
                        FieldName           = fieldName,
                        FieldValue          = fieldValue,
                        AutoNumberingConfig = autoNumberConfig.Id
                    };

                    log.Log("Creating new stream ...");
                    stream.Id = service.Create(stream);
                    log.Log("Finished creating new stream.");
                }

                currentIndex = stream.CurrentIndex.GetValueOrDefault();
            }

            log.Log($"Current index: {currentIndex}.");

            // if invalid value, reset
            // if updating and not incrementing, then keep index, else increment index
            var index = currentIndex <= 0
                                ? 1
                                : (isUpdate && autoNumberConfig.IncrementOnUpdate != true
                                        ? currentIndex
                                        : currentIndex + 1);

            if (isReset)
            {
                index = resetValue;
            }

            log.Log($"New index: {index}.");

            if (isDefaultIndex)
            {
                updatedAutoNumbering.CurrentIndex = index;
            }
            else if (stream != null)
            {
                log.Log($"Updating stream with new index ...");
                service.Update(
                    new AutoNumberingStream
                {
                    Id           = stream.Id,
                    CurrentIndex = index
                });
                log.Log($"Finished updating stream with new index.");
            }

            return(index);
        }
        private string ProcessIndices(string generatedString, int padding, bool isUpdate, AutoNumbering updatedAutoNumbering)
        {
            #region Date stuff

            var resetInterval = autoNumberConfig.ResetInterval;
            var resetDate     = autoNumberConfig.ResetDate;
            var lastResetDate = autoNumberConfig.LastResetDate;
            var isReset       = false;
            var resetValue    = 0;

            // if index reset config is set, and the time has passed, then reset index to value set
            if (resetDate != null &&
                (resetInterval != AutoNumbering.ResetIntervalEnum.Never &&
                 DateTime.UtcNow >= resetDate.Value &&
                 (lastResetDate == null || lastResetDate < resetDate)))
            {
                lastResetDate = resetDate;

                // add the interval to the reset date
                switch (resetInterval)
                {
                case AutoNumbering.ResetIntervalEnum.Yearly:
                    resetDate = resetDate.Value.AddYears(1);
                    break;

                case AutoNumbering.ResetIntervalEnum.Monthly:
                    resetDate = resetDate.Value.AddMonths(1);
                    break;

                case AutoNumbering.ResetIntervalEnum.Daily:
                    resetDate = resetDate.Value.AddDays(1);
                    break;

                case AutoNumbering.ResetIntervalEnum.Once:
                case AutoNumbering.ResetIntervalEnum.Never:
                    break;

                default:
                    throw new InvalidPluginExecutionException("Interval does not exist in code. Please contact the administrator.");
                }

                isReset    = true;
                resetValue = autoNumberConfig.ResetIndex ?? 0;
            }

            if (resetInterval == AutoNumbering.ResetIntervalEnum.Never)
            {
                resetDate = null;
            }

            #endregion

            generatedString = Regex.Replace(generatedString, @"{!index!(?:(\w+?)(?::(.*?))?)?}",
                                            match =>
            {
                var index = ProcessIndex(match, isReset, resetValue, isUpdate, updatedAutoNumbering);
                return(index.ToString().PadLeft(padding, '0'));
            });

            updatedAutoNumbering.ResetDate     = resetDate;
            updatedAutoNumbering.LastResetDate = lastResetDate;

            return(generatedString);
        }
        private Result GenerateString(bool isUpdate, AutoNumbering updatedAutoNumbering)
        {
            var parser = new Parser(service, image, log, autoNumberConfig.Owner.Id, orgId, cachedValues);

            log.Log("Preparing attribute variables ...");
            var generatedString = parser.ParseAttributeVariables(autoNumberConfig.FormatString ?? "");

            log.Log($"Generated string: {generatedString}");

            if (!isInlineConfig)
            {
                if (Regex.Matches(generatedString, @"{!param!.+?}").Count > 0)
                {
                    log.Log("Preparing param variables ...");
                    generatedString = parser.ParseParamVariables(generatedString, inputParams);
                    log.Log($"Generated string: {generatedString}");
                }
            }

            if (!isInlineConfig)
            {
                log.Log("Preparing random string variables ...");

                if (autoNumberConfig.IsRandomLetterStart == null || autoNumberConfig.IsNumberLetterRatio == null)
                {
                    throw new InvalidPluginExecutionException(
                              "Couldn't find a setting for the ratio or letter start in the auto-numbering configuration.");
                }
            }

            generatedString = parser.ParseRandomStringVariables(generatedString, autoNumberConfig.IsRandomLetterStart == true,
                                                                (autoNumberConfig.IsNumberLetterRatio == true && autoNumberConfig.NumberLetterRatio != null)
                                        ? autoNumberConfig.NumberLetterRatio.Value
                                        : -1);
            log.Log($"Generated string: {generatedString}");

            log.Log("Preparing date variables ...");
            generatedString = parser.ParseDateVariables(generatedString);
            log.Log($"Generated string: {generatedString}");

            if (!isInlineConfig)
            {
                log.Log("Preparing index ...");
                log.Log("Preparing padding ...");

                if (autoNumberConfig.IndexPadding == null)
                {
                    throw new InvalidPluginExecutionException("Couldn't find the padding in the auto-numbering configuration.");
                }

                var padding = autoNumberConfig.IndexPadding >= 0 ? autoNumberConfig.IndexPadding : 0;

                log.Log("Preparing autonumber variable ...");
                generatedString = ProcessIndices(generatedString, padding.Value, isUpdate, updatedAutoNumbering);
                log.Log($"Generated string: {generatedString}");
            }

            if (!isInlineConfig && !string.IsNullOrEmpty(autoNumberConfig.ReplacementCharacters))
            {
                log.Log("Replacing characters ...");
                var pairs = autoNumberConfig.ReplacementCharacters.Split(';').Select(e => e.Split(',')).ToArray();

                if (pairs.Any(e => e.Length < 2))
                {
                    throw new InvalidPluginExecutionException(
                              $"Replacement Characters' config is invalid: {autoNumberConfig.ReplacementCharacters}.");
                }

                foreach (var pair in pairs)
                {
                    generatedString = Regex.Replace(generatedString, pair[0], pair[1]);
                }

                log.Log($"Generated string: {generatedString}");
            }

            return
                (new Result
            {
                Index = updatedAutoNumbering.CurrentIndex.GetValueOrDefault(),
                IndexString = updatedAutoNumbering.CurrentIndex.GetValueOrDefault().ToString(),
                GeneratedString = generatedString
            });
        }
        /// <summary>
        /// A plug-in that creates a follow-up task activity when a new account is created.
        /// </summary>
        /// <remarks>Register this plug-in on the Create message, account entity,
        /// and asynchronous mode.
        /// </remarks>
        public void Execute(IServiceProvider serviceProvider)
        {
            //Extract the tracing service for use in debugging sandboxed plug-ins.
            ITracingService tracingService =
                (ITracingService)serviceProvider.GetService(typeof(ITracingService));

            // Obtain the execution context from the service provider.
            IPluginExecutionContext context = (IPluginExecutionContext)
                                              serviceProvider.GetService(typeof(IPluginExecutionContext));

            // The InputParameters collection contains all the data passed in the message request.
            if (context.InputParameters.Contains("Target") &&
                context.InputParameters["Target"] is Entity)
            {
                // Obtain the target entity from the input parameters.
                Entity entity = (Entity)context.InputParameters["Target"];

                if (entity.LogicalName != "gcbase_fundingcase")
                {
                    return;
                }

                FaultException ex1 = new FaultException();
                //  throw new InvalidPluginExecutionException("test", ex1);

                try
                {
                    //// Obtain the organization service reference.
                    IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
                    IOrganizationService        service        = serviceFactory.CreateOrganizationService(context.UserId);

                    AutoNumbering autoNumbering = new AutoNumbering(entity, service);
                    String        caseNumber    = autoNumbering.getAutoNumber();

                    entity["gcbase_name"] = caseNumber;
                    service.Update(entity);
                    if (entity.Attributes.Contains("gcbase_amountsbyfiscalyearserver"))
                    {
                        char[] delimitedChar = { ';' };

                        Entity          fundingAmountByFY = new Entity("gcbase_fundingcaseamountbyfy");
                        string[]        yearlyAmounts     = entity.Attributes["gcbase_amountsbyfiscalyearserver"].ToString().Split(delimitedChar);
                        EntityReference fundCentre        = entity.GetAttributeValue <EntityReference>("gcbase_program");
                        foreach (string ya in yearlyAmounts)
                        {
                            fundingAmountByFY["gcbase_fundingcase"] = new EntityReference("gcbase_fundingcase", entity.Id);
                            //fys[index] = (string)Enum.GetName(typeof(goal_fiscalyear), year);
                            OptionSetValue fy             = new OptionSetValue();
                            var            indexForFY     = ya.IndexOf("Y");
                            var            indexForAmount = ya.IndexOf("-");
                            var            yearStr        = ya.Substring(indexForFY + 1, 4);
                            var            amountStr      = ya.Substring(indexForAmount + 1);
                            tracingService.Trace("year is:" + yearStr);
                            tracingService.Trace("amount is:" + amountStr);
                            Money amount = new Money(decimal.Parse(amountStr));
                            fy.Value = Int32.Parse(yearStr);
                            fundingAmountByFY["gcbase_fiscalyear"] = fy;
                            fundingAmountByFY["gcbase_amount"]     = amount;
                            fundingAmountByFY["gcbase_fundcentre"] = fundCentre;
                            tracingService.Trace("PostFundingCasePlugin: Creating the budget item.");
                            service.Create(fundingAmountByFY);
                            tracingService.Trace(ya);
                        }
                    }
                    if (entity.Attributes.Contains("gcbase_program"))
                    {
                        ColumnSet cols = new ColumnSet
                                         (
                            new String[] { "gcbase_fundingcaseriskrequired" }
                                         );

                        //program configuration options
                        var program = service.Retrieve("gcbase_fundcentre", entity.GetAttributeValue <EntityReference>("gcbase_program").Id, cols);
                        tracingService.Trace("there");
                        if (program.GetAttributeValue <Boolean>("gcbase_fundingcaseriskrequired"))
                        {
                            var            ratype    = new OptionSetHelper().getIndexOfLabel("gcbase_fundingcaseriskassessment", "gcbase_fundingcaseriskassessmenttype", "Initial", service);
                            OptionSetValue raTypeOpt = new OptionSetValue(ratype);

                            //create initial risk assessment - should be custom class since this will be reused by other plugins
                            if (!new RiskTemplate(null, service).generateRiskAssessment(entity, raTypeOpt))
                            {
                                throw new InvalidPluginExecutionException("The funding program is not fully configured therefore a funding case cannot be created yet", ex1);
                            }

                            //newRA.generateAssessment();
                        }


                        //var results = service.Retrieve("gcbase_fundcentre", entity.GetAttributeValue<Guid>("gcbase_program"), null);
                    }
                }
                catch (FaultException <OrganizationServiceFault> ex)
                {
                    throw new InvalidPluginExecutionException("An error occurred in the FollowupPlugin plug-in.", ex);
                }

                catch (Exception ex)
                {
                    tracingService.Trace("FollowupPlugin: {0}", ex.ToString());
                    throw;
                }
            }
        }
예제 #10
0
        internal static AutoNumbering GetAutoNumberingConfig(Entity target, string config,
                                                             IPluginExecutionContext context, IOrganizationService service, CrmLog log, out bool isBackLogged)
        {
            var xrmContext = new XrmServiceContext(service)
            {
                MergeOption = MergeOption.NoTracking
            };

            var configIds      = config.Split(',').Select(item => item.Trim()).ToArray();
            var isInlineConfig = config.Contains(";;");

            AutoNumbering autoNumberConfig = null;

            if (isInlineConfig)
            {
                autoNumberConfig = GetInlineConfig(config, context.UserId);
            }

            // get it once to check for generator field update below
            log.Log("Getting auto-numbering config ...");

            // if a condition is found in any of the configs, then don't throw an error if none match
            // it simply means that the user wants the auto-numbering to work only if the condition is satisified
            // this is useful for multiple fields
            var isConditioned = false;

            // if using a backlog, then no need to lock
            isBackLogged = false;

            if (!isInlineConfig)
            {
                var autoNumberConfigTemp = GetBackloggedConfig(context, service, log);

                if (autoNumberConfigTemp == null)
                {
                    foreach (var configId in configIds)
                    {
                        autoNumberConfigTemp =
                            (from autoNumberQ in xrmContext.AutoNumberingSet
                             where autoNumberQ.UniqueID == configId || autoNumberQ.Name == configId &&
                             autoNumberQ.Status == AutoNumbering.StatusEnum.Active
                             select autoNumberQ).FirstOrDefault();

                        if (autoNumberConfigTemp == null)
                        {
                            continue;
                        }

                        if (autoNumberConfigTemp.Condition != null)
                        {
                            isConditioned = true;
                            log.Log($"Checking condition for '{autoNumberConfigTemp.Name}':'{autoNumberConfigTemp.Id}' ...");
                            var parsedCondition = ParseAttributeVariables(service, autoNumberConfigTemp.Condition, target,
                                                                          context.UserId, context.OrganizationId.ToString());
                            var isConditionMet = IsConditionMet(service, parsedCondition,
                                                                target.ToEntityReference(), context.OrganizationId.ToString());

                            if (isConditionMet)
                            {
                                log.Log("Condition met for auto-numbering record.");
                                autoNumberConfig = autoNumberConfigTemp;
                                break;
                            }

                            log.Log("Condition not met for auto-numbering record.");
                        }
                        else if (autoNumberConfig == null)
                        {
                            autoNumberConfig = autoNumberConfigTemp;
                        }
                    }
                }
                else
                {
                    autoNumberConfig = autoNumberConfigTemp;
                    isBackLogged     = true;
                }
            }

            return(PreValidation(service, target, autoNumberConfig, log, isConditioned, isBackLogged));
        }
예제 #11
0
        internal static int GetNextIndex(AutoNumbering autoNumberConfig, AutoNumbering updatedAutoNumbering)
        {
            #region Date stuff

            var resetInterval = autoNumberConfig.ResetInterval;
            var resetDate     = autoNumberConfig.ResetDate;
            var lastResetDate = autoNumberConfig.LastResetDate;
            var isReset       = false;
            var resetValue    = 0;

            // if index reset config is set, and the time has passed, then reset index to value set
            if (resetDate != null &&
                (resetInterval != AutoNumbering.ResetIntervalEnum.Never &&
                 DateTime.UtcNow >= resetDate.Value &&
                 (lastResetDate == null || lastResetDate < resetDate)))
            {
                lastResetDate = resetDate;

                // add the interval to the reset date
                switch (resetInterval)
                {
                case AutoNumbering.ResetIntervalEnum.Yearly:
                    resetDate = resetDate.Value.AddYears(1);
                    break;

                case AutoNumbering.ResetIntervalEnum.Monthly:
                    resetDate = resetDate.Value.AddMonths(1);
                    break;

                case AutoNumbering.ResetIntervalEnum.Daily:
                    resetDate = resetDate.Value.AddDays(1);
                    break;

                case AutoNumbering.ResetIntervalEnum.Once:
                case AutoNumbering.ResetIntervalEnum.Never:
                    break;

                default:
                    throw new InvalidPluginExecutionException("Interval does not exist in code. Please contact the administrator.");
                }

                isReset    = true;
                resetValue = autoNumberConfig.ResetIndex ?? 0;
            }

            if (resetInterval == AutoNumbering.ResetIntervalEnum.Never)
            {
                resetDate = null;
            }

            #endregion

            var currentIndex = autoNumberConfig.CurrentIndex.GetValueOrDefault();

            // if invalid value, reset
            // if updating and not incrementing, then keep index, else increment index
            var index = currentIndex <= 0 ? 1 : currentIndex + 1;

            if (isReset)
            {
                index = resetValue;
            }

            updatedAutoNumbering.ResetDate     = resetDate;
            updatedAutoNumbering.LastResetDate = lastResetDate;

            return(index);
        }
예제 #12
0
        internal static AutoNumbering PreValidation(IOrganizationService service, Entity target,
                                                    AutoNumbering autoNumberingConfig, CrmLog log, bool isConditioned, bool isBackLogged)
        {
            if (autoNumberingConfig == null)
            {
                // condition satisfaction failed before, so there's nothing to do here
                if (isConditioned)
                {
                    return(null);
                }

                throw new InvalidPluginExecutionException("Couldn't find an auto-numbering configuration.");
            }

            // if the auto-numbering is inactive, then don't apply
            if (autoNumberingConfig.Status == AutoNumbering.StatusEnum.Inactive)
            {
                //throw new InvalidPluginExecutionException("Autonumbering config record is inactive.");
                log.Log("AutoNumbering record is inactive.");
                return(null);
            }

            // exit if auto-number field is updating to prevent looping
            if (target != null && autoNumberingConfig.FieldLogicalName != null &&
                target.Contains(autoNumberingConfig.FieldLogicalName))
            {
                log.Log("Numbering is in progress in another instance.");
                return(null);
            }

            if (autoNumberingConfig.Id == Guid.Empty)
            {
                log.Log("Using inline config.");
                return(autoNumberingConfig);
            }

            if (autoNumberingConfig.Condition != null &&
                autoNumberingConfig.EntityLogicalName_ldv_EntityLogicalName == null)
            {
                throw new InvalidPluginExecutionException("Condition is set but entity name is not set in auto-numbering config.");
            }

            // only lock if an index is needed
            if (autoNumberingConfig.FormatString.Contains("{!index!}") && !isBackLogged)
            {
                log.Log("Locking ...", LogLevel.Debug);

                // ensure locking
                service.Update(
                    new AutoNumbering
                {
                    Id      = autoNumberingConfig.Id,
                    Locking = new Random().Next(999999, 999999999).ToString()
                });

                log.Log("Refetching numbering record ...", LogLevel.Debug);

                // get it again to ensure locking took effect
                var currentIndex =
                    (from autoNumberQ in new XrmServiceContext(service).AutoNumberingSet
                     where autoNumberQ.AutoNumberingId == autoNumberingConfig.Id &&
                     autoNumberQ.Status == AutoNumbering.StatusEnum.Active
                     select autoNumberQ.CurrentIndex).First();

                autoNumberingConfig.CurrentIndex = currentIndex;
            }

            return(autoNumberingConfig);
        }
 /// <summary>
 ///   Default constructor that setup the attribute type
 /// </summary>
 public DocumentContextInterpreter()
 {
     Numbering    = new AutoNumbering();
     ShapeManager = new ContextShapeManager();
     ActiveSketch = -1;
 }
예제 #14
0
        private void AllocateBacklog(AutoNumbering config)
        {
            var triggerId = config.TriggerID;
            var index     = config.CurrentIndex;
            var threshold = config.BacklogThreshold;

            var backlogEntry =
                new AutoNumberingBacklog
            {
                TriggerID           = triggerId,
                AutoNumberingConfig = config.Id,
            };

            // get an old backLog, if not, then create a new one
            if (threshold.HasValue)
            {
                var queryXml =
                    $@"<fetch top='1' >
  <entity name='ldv_autonumberingbacklog' >
    <attribute name='ldv_autonumberingbacklogid' />
    <attribute name='ldv_indexvalue' />
    <attribute name='ldv_triggerid' />
    <filter>
      <condition attribute='modifiedon' operator='olderthan-x-minutes' value='{threshold.Value}' />
      <condition attribute='ldv_autonumberingconfigid' operator='eq' value='{config.Id}' />
    </filter>
    <order attribute='ldv_indexvalue' />
  </entity>
</fetch>";
                Log.LogDebug("Query XML", queryXml);

                Log.Log($"Retrieving first old backlog entry older than {threshold.Value} ...");
                var backlogEntryTemp = Service.RetrieveMultiple(new FetchExpression(queryXml)).Entities.FirstOrDefault();
                Log.Log($"Finished retrieving first old backlog entry.");

                if (backlogEntryTemp == null)
                {
                    Log.Log($"Couldn't find any old backlog entries.");

                    var updatedAutoNumbering =
                        new AutoNumbering
                    {
                        Id = config.Id
                    };

                    backlogEntry.IndexValue = Helper.GetNextIndex(config, updatedAutoNumbering);

                    Log.Log("Incrementing auto-numbering config's index ...");
                    Service.Update(updatedAutoNumbering);
                    Log.Log("Finished incrementing auto-numbering config's index.");
                }
                else
                {
                    backlogEntry = backlogEntryTemp.ToEntity <AutoNumberingBacklog>();
                }
            }

            backlogEntry.TriggerID = triggerId;
            backlogEntry.KeyAttributes.Add(AutoNumberingBacklog.Fields.TriggerID, triggerId);

            Log.Log($"Upserting backlog with trigger ID '{triggerId}' and index {index} ...");
            Service.Execute(
                new UpsertRequest
            {
                Target = backlogEntry
            });
            Log.Log($"Finished Upserting backLog.");
        }