Ejemplo n.º 1
0
        /// <summary>
        ///     Builds a predicate that examines the raw data (as its native .Net type) to determine if
        ///     it passes the specified filter.
        /// </summary>
        /// <remarks>
        ///     This overload assumes that the values will not be null.
        /// </remarks>
        /// <param name="condition">The condition to be applied.</param>
        /// <param name="gridResultColumn">The grid result column.</param>
        /// <param name="conditionalFormatter">The conditional formatter.</param>
        /// <returns>A predicate that accepts a data value and returns true if the value is acceptable on the basis of the filter.</returns>
        private static Predicate <object> BuildValueFilterPredicateNoNulls(Condition condition, ResultColumn gridResultColumn, ConditionalFormatter conditionalFormatter)
        {
            // Get and check argument
            TypedValue  argument  = condition.Argument;
            string      sArgument = null;
            IComparable cArgument = null;

            // Handle null strings. TODO: Improve this hack
            if (argument != null && argument.Value == null && argument.Type is StringType)
            {
                argument.Value = "";
            }

            if (argument == null || argument.Value == null)
            {
                if (ConditionTypeHelper.GetArgumentCount(condition.Operator) != 0)
                {
                    throw new ArgumentException(@"Condition has no (or null) argument.", "condition");
                }
            }
            else
            {
                sArgument = argument.Value as string;
                cArgument = argument.Value as IComparable;
            }

            bool isDate     = condition.ColumnType is DateType;
            bool isCurrency = condition.ColumnType is CurrencyType;

            // Return lambda to evaluate test
            // 'cell' is statically type object
            switch (condition.Operator)
            {
            case ConditionType.Unspecified:
                return(cell => true);    // assert false - predicates should not be built from filters with unspecified operators. Silently ignore.

            case ConditionType.Equal:
                if (argument.Type is StringType)
                {
                    return(cell => ((string)cell).Equals(argument.ValueString, StringComparison.CurrentCultureIgnoreCase));
                }
                return(cell => argument != null && argument.Value.Equals(isCurrency ? ConvertCurrencyCell(cell, condition.ColumnType) : cell));

            case ConditionType.NotEqual:
                if (argument.Type is StringType)
                {
                    return(cell => !((string)cell).Equals(argument.ValueString, StringComparison.CurrentCultureIgnoreCase));
                }
                return(cell => argument != null && !argument.Value.Equals(isCurrency ? ConvertCurrencyCell(cell, condition.ColumnType) : cell));

            case ConditionType.GreaterThan:
                return(cell => cArgument != null && cArgument.CompareTo(isCurrency ? ConvertCurrencyCell(cell, condition.ColumnType) : cell) < 0);

            case ConditionType.GreaterThanOrEqual:
                return(cell => cArgument != null && cArgument.CompareTo(isCurrency ? ConvertCurrencyCell(cell, condition.ColumnType) : cell) <= 0);

            case ConditionType.LessThan:
                return(cell => cArgument != null && cArgument.CompareTo(isCurrency ? ConvertCurrencyCell(cell, condition.ColumnType) : cell) > 0);

            case ConditionType.LessThanOrEqual:
                return(cell => cArgument != null && cArgument.CompareTo(isCurrency ? ConvertCurrencyCell(cell, condition.ColumnType) : cell) >= 0);

            case ConditionType.Contains:
                return(cell => ((string)cell).IndexOf(sArgument, StringComparison.CurrentCultureIgnoreCase) >= 0);

            case ConditionType.StartsWith:
                return(cell => ((string)cell).StartsWith(sArgument, StringComparison.CurrentCultureIgnoreCase));

            case ConditionType.EndsWith:
                return(cell => ((string)cell).EndsWith(sArgument, StringComparison.CurrentCultureIgnoreCase));

            case ConditionType.AnyOf:
                return(cell => AnyOf((long)cell, condition.Arguments));

            case ConditionType.AnyExcept:
                return(cell => AnyExcept((long)cell, condition.Arguments));

            case ConditionType.Today:
            case ConditionType.ThisMonth:
            case ConditionType.ThisQuarter:
            case ConditionType.ThisYear:
            case ConditionType.CurrentFinancialYear:
            case ConditionType.LastNDays:
            case ConditionType.NextNDays:
            case ConditionType.LastNMonths:
            case ConditionType.NextNMonths:
            case ConditionType.LastNQuarters:
            case ConditionType.NextNQuarters:
            case ConditionType.LastNYears:
            case ConditionType.NextNYears:
            case ConditionType.LastNFinancialYears:
            case ConditionType.NextNFinancialYears:
            case ConditionType.LastNDaysTillNow:
            case ConditionType.NextNDaysFromNow:
            case ConditionType.ThisWeek:
            case ConditionType.LastNWeeks:
            case ConditionType.NextNWeeks:
                return(cell =>
                {
                    DateTime minDate, maxDate;
                    var cellAsDateTime = isDate ? (DateTime)cell : UtcToLocal((DateTime)cell);

                    const int startMonthOfFinancialYear = 7;     //TODO: this comes from old code. Reported as a bug to Diana to improve to respect tenant FY configuration.
                    PeriodConditionHelper.GetPeriodFromConditionType(condition.Operator, DateTime.Today, cArgument != null ? cArgument as int?: null, startMonthOfFinancialYear, isDate, out minDate, out maxDate);

                    return cellAsDateTime >= minDate && cellAsDateTime < maxDate;
                });

            case ConditionType.DateEquals:
            {
                if (argument != null && argument.Value != null)
                {
                    DateTime today     = ((DateTime)argument.Value).Date;
                    DateTime threshold = today.AddDays(1);
                    return(cell =>
                        {
                            DateTime dCell = isDate ? (DateTime)cell : UtcToLocal((DateTime)cell);
                            return threshold.CompareTo(dCell) > 0 && today.CompareTo(dCell) <= 0;
                        });
                }
            }
            break;

            case ConditionType.IsTrue:
                return(cell => ((bool)cell));

            case ConditionType.IsFalse:
                return(cell => !((bool)cell));

            case ConditionType.IsNull:
                return(cell => string.Empty.Equals(cell));    // this method does not get called if it is truly null

            case ConditionType.IsNotNull:
                return(cell => !string.Empty.Equals(cell));    // this method does not get called if it is truly null

            case ConditionType.CurrentUser:
                return(IsCurrentUser);

            case ConditionType.AnyBelowStructureLevel:
            case ConditionType.AnyAboveStructureLevel:
            case ConditionType.AnyAtOrAboveStructureLevel:
            case ConditionType.AnyAtOrBelowStructureLevel:
                return(cell => ApplyStructureViewCondition((string)cell, condition, gridResultColumn, conditionalFormatter));

            default:
                throw new Exception("Unknown filter operator.");
            }

            return(null);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Apply the specified structure level condition to the given cell.
        /// </summary>
        /// <param name="cellValue">The cell value.</param>
        /// <param name="condition">The condition.</param>
        /// <param name="gridResultColumn">The grid result column.</param>
        /// <param name="conditionalFormatter">The current conditional formatter.</param>
        /// <returns>True if the operator and arguments apply, false otherwuse</returns>
        private static bool ApplyStructureViewCondition(string cellValue, Condition condition, ResultColumn gridResultColumn, ConditionalFormatter conditionalFormatter)
        {
            IList <TypedValue> arguments         = condition.Arguments;
            ConditionType      conditionOperator = condition.Operator;

            // Sanity check
            if (arguments == null || arguments.Count <= 0 || string.IsNullOrEmpty(cellValue) || gridResultColumn == null)
            {
                return(false);
            }

            var structureViewExpression = gridResultColumn.RequestColumn.Expression as StructureViewExpression;

            if (structureViewExpression == null)
            {
                return(false);
            }

            // Get the structure levels for this structure view.
            Dictionary <long, StructureViewLevelsValue> structureViewLevels;

            if (!conditionalFormatter._structureViewLevelsCache.TryGetValue(structureViewExpression.StructureViewId.Id, out structureViewLevels))
            {
                structureViewLevels = GetStructureViewLevels(structureViewExpression);
                conditionalFormatter._structureViewLevelsCache[structureViewExpression.StructureViewId.Id] = structureViewLevels;
            }

            int colonIndex = cellValue.IndexOf(':');

            if (colonIndex <= 0)
            {
                return(false);
            }

            // Parse the entity id of the current structure level from the cell value
            string idString = cellValue.Substring(0, colonIndex);
            long   cellEntityId;

            if (!long.TryParse(idString, out cellEntityId))
            {
                return(false);
            }

            // Get all the levels to/from this structure level
            StructureViewLevelsValue levelsValue;

            if (!structureViewLevels.TryGetValue(cellEntityId, out levelsValue))
            {
                return(false);
            }

            // Check the arguments
            foreach (var argValueAsString in arguments.Select(argument => argument.Value.ToString()))
            {
                // Check for equality
                if (argValueAsString == idString &&
                    (conditionOperator == ConditionType.AnyAtOrAboveStructureLevel ||
                     conditionOperator == ConditionType.AnyAtOrBelowStructureLevel))
                {
                    return(true);
                }

                long argValueAsLong;
                if (!long.TryParse(argValueAsString, out argValueAsLong))
                {
                    continue;
                }

                // Check hierarchy
                switch (conditionOperator)
                {
                case ConditionType.AnyAboveStructureLevel:
                case ConditionType.AnyAtOrAboveStructureLevel:
                    if (levelsValue.ToLevelIds.Contains(argValueAsLong))
                    {
                        return(true);
                    }
                    break;

                case ConditionType.AnyAtOrBelowStructureLevel:
                case ConditionType.AnyBelowStructureLevel:
                    if (levelsValue.FromLevelIds.Contains(argValueAsLong))
                    {
                        return(true);
                    }
                    break;
                }
            }

            return(false);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Predicates for rule.
        /// </summary>
        /// <param name="condition">The condition.</param>
        /// <param name="isResourceCondition">if set to <c>true</c> [is resource condition].</param>
        /// <param name="gridResultColumn">The result column.</param>
        /// <param name="conditionalFormatter">The conditional formatter column.</param>
        /// <returns>Predicate{System.Object}.</returns>
        private static Predicate <object> PredicateForRule(Condition condition, bool isResourceCondition, ResultColumn gridResultColumn, ConditionalFormatter conditionalFormatter)
        {
            try
            {
                Predicate <object> valueFilterPredicate = BuildValueFilterPredicateNoNulls(condition, gridResultColumn, conditionalFormatter);

                return(value =>
                {
                    try
                    {
                        // Handle nulls
                        // for now ANY type of filter on a column will reject null values
                        if (value == null || value is DBNull)
                        {
                            switch (condition.Operator)
                            {
                            case ConditionType.NotEqual:
                                value = "";
                                break;

                            case ConditionType.IsNull:
                                return true;

                            case ConditionType.IsNotNull:
                                return false;

                            case ConditionType.AnyExcept:
                                return true;

                            default:
                                return false;
                            }
                        }

                        // Handle transforms
                        if (isResourceCondition)
                        {
                            var xml = (string)value;
                            if (condition.Operator == ConditionType.AnyExcept ||
                                condition.Operator == ConditionType.AnyOf ||
                                condition.Operator == ConditionType.CurrentUser)
                            {
                                value = DatabaseTypeHelper.GetEntityXmlId(xml);
                            }
                            else
                            {
                                value = DatabaseTypeHelper.GetEntityXmlName(xml);
                            }
                        }

                        // Evaluate the specific predicate
                        return valueFilterPredicate(value);
                    }
                    catch
                    {
                        return false;
                        //throw new Exception( string.Format( "Predicate failed. Data={0} {1}. Expected={2}", value == null ? "null" : value.GetType( ).Name, value, condition.ColumnType ), ex );
                    }
                });
            }
            catch (ArgumentException)
            {
                return(null); //  argument does not exist .. return null
            }
        }