private bool HasCorrectOrder(IEnumerable <FormulaItem> formulaItems)
        {
            var items = formulaItems?.ToList();

            if (items == null || items.IsEmpty())
            {
                return(false);
            }
            if (items.Count() == 1)
            {
                return(items[0].Type == FormulaItemType.Number || items[0].Type == FormulaItemType.Column);
            }
            FormulaItem lastItem = items[items.Count() - 1];

            if (lastItem.Type == FormulaItemType.Function)
            {
                return(false);
            }
            var functions = GetFunctions(items).ToList();

            for (var i = 0; i < items.Count() - 1; i++)
            {
                FormulaItem currentItem = items[i];
                FormulaItem nextItem    = items[i + 1];
                switch (currentItem.Type)
                {
                case FormulaItemType.Number: {
                    if (nextItem.Type == FormulaItemType.Column ||
                        nextItem.Type == FormulaItemType.Function)
                    {
                        return(false);
                    }
                    break;
                }

                case FormulaItemType.Column: {
                    if (nextItem.Type == FormulaItemType.Column ||
                        nextItem.Type == FormulaItemType.Number ||
                        nextItem.Type == FormulaItemType.Function)
                    {
                        return(false);
                    }
                    break;
                }

                case FormulaItemType.Function: {
                    FunctionInfo functionInfo
                        = functions.First(item => item.StartIndexInFormula.Equals(i));
                    if (!FunctionValidator.Validate(functionInfo) ||
                        IsNextElementAfterFunctionNotAllowed(items, functionInfo))
                    {
                        return(false);
                    }
                    i += functionInfo.Rule.FunctionMaxLengthExpectHeader;
                    break;
                }
                }
            }
            return(true);
        }
Example #2
0
        private bool HasCorrectOrder(IEnumerable <FormulaItem> formulaItems)
        {
            FormulaItem previousItem = null;

            foreach (var formulaItem in formulaItems)
            {
                if (previousItem == null)
                {
                    previousItem = formulaItem;
                    continue;
                }
                switch (previousItem.Type)
                {
                case FormulaItemType.Number: {
                    if (formulaItem.Type.Equals(FormulaItemType.Column))
                    {
                        return(false);
                    }
                    break;
                }

                case FormulaItemType.Column: {
                    if (formulaItem.Type.Equals(FormulaItemType.Column) ||
                        formulaItem.Type.Equals(FormulaItemType.Number))
                    {
                        return(false);
                    }
                    break;
                }
                }
                previousItem = formulaItem;
            }
            return(true);
        }
 private static void ValidateArguments(FormulaItem formulaItem)
 {
     formulaItem.CheckArgumentNull(nameof(formulaItem));
     if (formulaItem.Type != FormulaItemType.Function)
     {
         throw new ArgumentException($"Expected formula item with type " +
                                     $"{FormulaItemType.Function.ToString()} but was passed item with type {formulaItem.Type.ToString()}.");
     }
 }
        private void CalcFunctionCell(IEnumerable <TableCell> columnValues, IEnumerable <TableCell> summaryCells,
                                      ForecastColumn funcColumn, FormulaItem function)
        {
            TableCell summaryCell  = GetSummaryCell(summaryCells, funcColumn);
            string    functionCode = function.Value;

            summaryCell.FunctionsValueMap = summaryCell.FunctionsValueMap ?? new Dictionary <string, double>();
            double value = CalcColumnSummary(columnValues, funcColumn, functionCode);

            summaryCell.FunctionsValueMap[functionCode] = value;
        }
 private bool IsValidItem(FormulaItem itemToValidate, FormulaItem patternItem)
 {
     if (itemToValidate.Type != patternItem.Type)
     {
         return(false);
     }
     if (itemToValidate.Type == FormulaItemType.Function)
     {
         return(IsFunctionTypeSupported(itemToValidate.Value));
     }
     if (patternItem.Value != null)
     {
         return(itemToValidate.Value.Equals(patternItem.Value));
     }
     return(true);
 }
        /// <summary>
        /// Gets functions from specified formula.
        /// </summary>
        /// <param name="formulaItems">Formula items.</param>
        /// <returns>List of functions witch contains in specified formula.</returns>
        public IEnumerable <FunctionInfo> GetFunctions(IEnumerable <FormulaItem> formulaItems)
        {
            var items  = formulaItems.ToList();
            var result = new List <FunctionInfo>();

            for (var i = 0; i < items.Count(); i++)
            {
                FormulaItem currentItem = items[i];
                if (currentItem.Type == FormulaItemType.Function)
                {
                    var funcInfo = new FunctionInfo(formulaItems, i);
                    result.Add(funcInfo);
                }
            }
            return(result);
        }
        private bool IsNextElementAfterFunctionNotAllowed(List <FormulaItem> items, FunctionInfo functionInfo)
        {
            int nextElementIndex
                = functionInfo.StartIndexInFormula + functionInfo.Rule.FunctionMaxLength;
            bool isNextElementNotOutOfListRange = nextElementIndex < items.Count();

            if (isNextElementNotOutOfListRange)
            {
                FormulaItem nextItem = items[nextElementIndex];
                if (nextItem.Type == FormulaItemType.Column ||
                    nextItem.Type == FormulaItemType.Number ||
                    nextItem.Type == FormulaItemType.Function)
                {
                    return(true);
                }
            }
            return(false);
        }
        private bool IsFunctionMatchesPattern(FunctionInfo functionInfo)
        {
            var formulaItems = functionInfo.Body?.ToList();

            if (formulaItems == null || formulaItems.Count() != functionInfo.Rule.FunctionMaxLength)
            {
                return(false);
            }
            var functionPattern = functionInfo.Rule.Pattern;

            for (var i = 0; i < functionPattern.Count(); i++)
            {
                FormulaItem itemToValidate    = formulaItems[i];
                FormulaItem validationPattern = functionPattern[i];
                if (!IsValidItem(itemToValidate, validationPattern))
                {
                    return(false);
                }
            }
            return(true);
        }
        private string GetFormula(IEnumerable <FormulaItem> formulaItems, IDictionary <string, string> injectedValues)
        {
            var formula = string.Empty;
            var items   = formulaItems.ToList();
            IEnumerable <FunctionInfo> functions = null;

            for (var i = 0; i < items.Count(); i++)
            {
                FormulaItem currentItem = items[i];
                switch (currentItem.Type)
                {
                case FormulaItemType.Column: {
                    formula += GetInjectedValue(injectedValues, currentItem.Value);
                    break;
                }

                case FormulaItemType.Number:
                case FormulaItemType.Operand:
                    formula += currentItem.Value;
                    break;

                case FormulaItemType.Function: {
                    functions = functions ?? GetFunctions(formulaItems);
                    var    function      = functions.First(f => f.StartIndexInFormula == i);
                    var    columnOperand = function.Operands.First();
                    string key           = FormFunctionValueKey(currentItem.Value, columnOperand.Value);
                    formula += GetInjectedValue(injectedValues, key);
                    i       += function.Rule.FunctionMaxLengthExpectHeader;
                    break;
                }

                default:
                    throw new Exception(
                              string.Format("Formula type {0} not supported", currentItem.Type.ToString()));
                }
            }
            return(formula);
        }
 /// <summary>
 /// Returns function rules based on function type.
 /// </summary>
 /// <param name="item">The function formula item.</param>
 /// <returns><see cref="FunctionRule"/>The function rule.</returns>
 public static FunctionRule GetRule(FormulaItem item)
 {
     ValidateArguments(item);
     return(new SimpleFunctionRules());
 }