Пример #1
0
        private void CheckForEnumIssues(CustomContext context, SchemaJsonCalculation calculation)
        {
            if (calculation.Type == FundingCalculationType.Enum)
            {
                if (calculation.AllowedEnumTypeValues.IsNullOrEmpty())
                {
                    AddFailure(context, "Calculation",
                               $"Calculation with name '{calculation.Name}' and id : '{calculation.TemplateCalculationId}' " +
                               "is of type Enum but has missing allowed enum values.");
                }
                else
                {
                    if (calculation.AllowedEnumTypeValues.Any(x => x.IsNullOrEmpty()))
                    {
                        AddFailure(context, "Calculation",
                                   $"Calculation with name '{calculation.Name}' and id '{calculation.TemplateCalculationId}' " +
                                   "contains a null or empty allowed enum value");
                    }

                    var duplicates = calculation.AllowedEnumTypeValues
                                     .Select((t, i) => new { Index = i, Text = t })
                                     .GroupBy(g => g.Text)
                                     .Where(g => g.Count() > 1)
                                     .Select(x => x.Key)
                                     .ToList();
                    if (duplicates.Any())
                    {
                        AddFailure(context, "Calculation",
                                   $"Calculation with name '{calculation.Name}' and id '{calculation.TemplateCalculationId}' " +
                                   $"has duplicate allowed enum values for '{string.Join("', '", duplicates)}'");
                    }
                }
            }
        }
Пример #2
0
        private void CheckForGroupRateIssues(CustomContext context, SchemaJsonCalculation calculation)
        {
            if (calculation.AggregationType == AggregationType.GroupRate)
            {
                if (calculation.GroupRate == null)
                {
                    AddFailure(context, "Calculation",
                               $"Calculation with name '{calculation.Name}' and id : '{calculation.TemplateCalculationId}' " +
                               "has an aggregation type of Group Rate but is missing numerator & denominator.");
                }
                else
                {
                    var numeratorCalculationMatches = _flattenedCalculations
                                                      .Count(c => c.TemplateCalculationId == calculation.GroupRate.Numerator);
                    if (numeratorCalculationMatches == 0)
                    {
                        AddFailure(context, "Calculation",
                                   $"Calculation with name '{calculation.Name}' and id : '{calculation.TemplateCalculationId}' " +
                                   $"has a numerator with TemplateCalculationId {calculation.GroupRate.Numerator} " +
                                   "that does not refer to a calculation in this template.");
                    }

                    var denominatorCalculationMatches = _flattenedCalculations
                                                        .Count(c => c.TemplateCalculationId == calculation.GroupRate.Denominator);
                    if (denominatorCalculationMatches == 0)
                    {
                        AddFailure(context, "Calculation",
                                   $"Calculation with name '{calculation.Name}' and id : '{calculation.TemplateCalculationId}' " +
                                   $"has a denominator with TemplateCalculationId {calculation.GroupRate.Denominator} " +
                                   "that does not refer to a calculation in this template.");
                    }

                    if (calculation.GroupRate.Numerator == calculation.GroupRate.Denominator)
                    {
                        AddFailure(context, "Calculation",
                                   $"Calculation with name '{calculation.Name}' and id : '{calculation.TemplateCalculationId}' " +
                                   "has the same numerator & denominator for Group Rate.");
                    }

                    if (calculation.GroupRate.Numerator == calculation.TemplateCalculationId)
                    {
                        AddFailure(context, "Calculation",
                                   $"Calculation with name '{calculation.Name}' and id : '{calculation.TemplateCalculationId}' " +
                                   "has a Group Rate numerator referring to its own TemplateCalculationId.");
                    }

                    if (calculation.GroupRate.Denominator == calculation.TemplateCalculationId)
                    {
                        AddFailure(context, "Calculation",
                                   $"Calculation with name '{calculation.Name}' and id : '{calculation.TemplateCalculationId}' " +
                                   "has a Group Rate denominator referring to its own TemplateCalculationId.");
                    }
                }
            }
        }
Пример #3
0
 private void CheckForNonMatchingChildren(CustomContext context, SchemaJsonCalculation calculation, SchemaJsonCalculation clone)
 {
     if (!clone.Calculations.IsNullOrEmpty() &&
         !clone.Calculations.All(_ =>
                                 calculation.Calculations.AnyWithNullCheck() &&
                                 calculation.Calculations.Any(fl => fl.TemplateCalculationId == _.TemplateCalculationId)))
     {
         AddFailure(context, "Calculation",
                    $"Calculation with name '{clone.Name}' and id '{calculation.TemplateCalculationId}' " +
                    "has child calculations which don't match.");
     }
 }
Пример #4
0
        private void CheckForUniqueCalculationName(CustomContext context, SchemaJsonCalculation calculation)
        {
            int nameUsages = _flattenedCalculations.Count(x =>
                                                          x.Name.Equals(calculation.Name, StringComparison.OrdinalIgnoreCase) &&
                                                          x.TemplateCalculationId != calculation.TemplateCalculationId);

            if (nameUsages > 1)
            {
                AddFailure(context, "Calculation",
                           $"Calculation : '{calculation.Name}' and id : '{calculation.TemplateCalculationId}' " +
                           "has a duplicate name in the template with a different TemplateCalculationIds.");
            }
        }
 private static Calculation ToCalculation(this SchemaJsonCalculation source)
 {
     return(new Calculation
     {
         Name = source.Name,
         ValueFormat = source.ValueFormat.AsMatchingEnum <CalculationValueFormat>(),
         AggregationType = source.AggregationType.AsMatchingEnum <AggregationType>(),
         Type = source.Type.AsMatchingEnum <CalculationType>(),
         TemplateCalculationId = source.TemplateCalculationId,
         FormulaText = source.FormulaText,
         Calculations = source.Calculations?.Select(ToCalculation),
         GroupRate = ToGroupRate(source.GroupRate),
         PercentageChangeBetweenAandB = ToPercentageChangeBetweenAandB(source.PercentageChangeBetweenAandB),
         AllowedEnumTypeValues = source.AllowedEnumTypeValues?.Any() == true ? source.AllowedEnumTypeValues : null
     });
 }
Пример #6
0
            public override SchemaJsonCalculation ToCalculation(Calculation templateCalculation,
                                                                FundingCalculation publishedFundingCalculation,
                                                                IEnumerable <FundingCalculation> publishedFundingCalculations,
                                                                string providerId)
            {
                SchemaJsonCalculation schemaJsonCalculation = base.ToCalculation(templateCalculation,
                                                                                 publishedFundingCalculation,
                                                                                 publishedFundingCalculations,
                                                                                 providerId);

                PercentageChangeBetweenAandB templateCalculationPercentageChangeBetweenAandB = templateCalculation.PercentageChangeBetweenAandB;

                schemaJsonCalculation.PercentageChangeBetweenAandB = new SchemaJsonPercentageChangeBetweenAandB
                {
                    CalculationA = templateCalculationPercentageChangeBetweenAandB.CalculationA,
                    CalculationB = templateCalculationPercentageChangeBetweenAandB.CalculationB,
                    CalculationAggregationType = templateCalculationPercentageChangeBetweenAandB.CalculationAggregationType.ToString()
                };

                return(schemaJsonCalculation);
            }
Пример #7
0
        private void ValidateCalculation(CustomContext context, SchemaJsonCalculation calculation)
        {
            calculation.Name = calculation.Name.Trim();

            CheckForUniqueCalculationName(context, calculation);

            CheckForClonesWithDifferentValues(context, calculation);

            CheckForGroupRateIssues(context, calculation);

            CheckForPercentageChangeIssues(context, calculation);

            CheckForEnumIssues(context, calculation);

            if (calculation.Calculations != null)
            {
                foreach (SchemaJsonCalculation nestedCalculation in calculation.Calculations)
                {
                    ValidateCalculation(context, nestedCalculation);
                }
            }
        }
            public override SchemaJsonCalculation ToSchemaJsonCalculation(Calculation templateCalculation,
                                                                          FundingCalculation publishedFundingCalculation,
                                                                          IEnumerable <FundingCalculation> publishedFundingCalculations,
                                                                          string organisationGroupTypeIdentifier,
                                                                          string organisationGroupIdentifierValue)
            {
                SchemaJsonCalculation schemaJsonCalculation = base.ToSchemaJsonCalculation(templateCalculation,
                                                                                           publishedFundingCalculation,
                                                                                           publishedFundingCalculations,
                                                                                           organisationGroupTypeIdentifier,
                                                                                           organisationGroupIdentifierValue);

                GroupRate templateCalculationGroupRate = templateCalculation.GroupRate;

                schemaJsonCalculation.GroupRate = new SchemaJsonGroupRate
                {
                    Denominator = templateCalculationGroupRate.Denominator,
                    Numerator   = templateCalculationGroupRate.Numerator
                };

                return(schemaJsonCalculation);
            }
            public override SchemaJsonCalculation ToSchemaJsonCalculation(Calculation templateCalculation,
                                                                          FundingCalculation publishedFundingCalculation,
                                                                          IEnumerable <FundingCalculation> publishedFundingCalculations,
                                                                          string organisationGroupTypeIdentifier,
                                                                          string organisationGroupIdentifierValue)
            {
                SchemaJsonCalculation schemaJsonCalculation = base.ToSchemaJsonCalculation(templateCalculation,
                                                                                           publishedFundingCalculation,
                                                                                           publishedFundingCalculations,
                                                                                           organisationGroupTypeIdentifier,
                                                                                           organisationGroupIdentifierValue);

                PercentageChangeBetweenAandB templateCalculationPercentageChangeBetweenAandB = templateCalculation.PercentageChangeBetweenAandB;

                schemaJsonCalculation.PercentageChangeBetweenAandB = new SchemaJsonPercentageChangeBetweenAandB
                {
                    CalculationA = templateCalculationPercentageChangeBetweenAandB.CalculationA,
                    CalculationB = templateCalculationPercentageChangeBetweenAandB.CalculationB,
                    CalculationAggregationType = templateCalculationPercentageChangeBetweenAandB.CalculationAggregationType.ToString()
                };

                return(schemaJsonCalculation);
            }
Пример #10
0
        private void CheckForPercentageChangeIssues(CustomContext context, SchemaJsonCalculation calculation)
        {
            if (calculation.AggregationType == AggregationType.PercentageChangeBetweenAandB)
            {
                if (calculation.PercentageChangeBetweenAandB == null)
                {
                    AddFailure(context, "Calculation",
                               $"Calculation with name '{calculation.Name}' and id : '{calculation.TemplateCalculationId}' " +
                               "has an aggregation type of PercentageChangeBetweenAandB but is missing numerator & denominator.");
                }
                else
                {
                    var calculationAMatches = _flattenedCalculations
                                              .Where(c => c.TemplateCalculationId == calculation.PercentageChangeBetweenAandB.CalculationA);
                    if (!calculationAMatches.Any())
                    {
                        AddFailure(context, "Calculation",
                                   $"Calculation with name '{calculation.Name}' and id : '{calculation.TemplateCalculationId}' " +
                                   $"has CalculationA with TemplateCalculationId {calculation.PercentageChangeBetweenAandB.CalculationA} " +
                                   "that does not refer to a calculation in this template.");
                    }
                    else
                    {
                        if (calculationAMatches.Any(x =>
                                                    x.AggregationType == AggregationType.GroupRate &&
                                                    x.GroupRate != null &&
                                                    (x.GroupRate.Numerator == calculation.TemplateCalculationId ||
                                                     x.GroupRate.Denominator == calculation.TemplateCalculationId)))
                        {
                            AddFailure(context, "Calculation",
                                       $"Calculation with name '{calculation.Name}' and id : '{calculation.TemplateCalculationId}' " +
                                       $"has CalculationA with TemplateCalculationId {calculation.PercentageChangeBetweenAandB.CalculationA} " +
                                       "that contains a group rate referring back to this calculation.");
                        }

                        if (calculationAMatches.Any(x =>
                                                    x.AggregationType == AggregationType.PercentageChangeBetweenAandB &&
                                                    x.PercentageChangeBetweenAandB != null &&
                                                    (x.PercentageChangeBetweenAandB.CalculationA == calculation.TemplateCalculationId ||
                                                     x.PercentageChangeBetweenAandB.CalculationB == calculation.TemplateCalculationId)))
                        {
                            AddFailure(context, "Calculation",
                                       $"Calculation with name '{calculation.Name}' and id : '{calculation.TemplateCalculationId}' " +
                                       $"has CalculationA with TemplateCalculationId {calculation.PercentageChangeBetweenAandB.CalculationA} " +
                                       "that contains a PercentageChangeBetweenAandB referring back to this calculation.");
                        }
                    }

                    var calculationBMatches = _flattenedCalculations
                                              .Where(c => c.TemplateCalculationId == calculation.PercentageChangeBetweenAandB.CalculationB);
                    if (!calculationBMatches.Any())
                    {
                        AddFailure(context, "Calculation",
                                   $"Calculation with name '{calculation.Name}' and id : '{calculation.TemplateCalculationId}' " +
                                   $"has CalculationB with TemplateCalculationId {calculation.PercentageChangeBetweenAandB.CalculationB} " +
                                   "that does not refer to a calculation in this template.");
                    }
                    else
                    {
                        if (calculationBMatches.Any(x =>
                                                    x.AggregationType == AggregationType.GroupRate &&
                                                    x.GroupRate != null &&
                                                    (x.GroupRate.Numerator == calculation.TemplateCalculationId ||
                                                     x.GroupRate.Denominator == calculation.TemplateCalculationId)))
                        {
                            AddFailure(context, "Calculation",
                                       $"Calculation with name '{calculation.Name}' and id : '{calculation.TemplateCalculationId}' " +
                                       $"has CalculationB with TemplateCalculationId {calculation.PercentageChangeBetweenAandB.CalculationB} " +
                                       "that contains a group rate referring back to this calculation.");
                        }

                        if (calculationBMatches.Any(x =>
                                                    x.AggregationType == AggregationType.PercentageChangeBetweenAandB &&
                                                    x.PercentageChangeBetweenAandB != null &&
                                                    (x.PercentageChangeBetweenAandB.CalculationA == calculation.TemplateCalculationId ||
                                                     x.PercentageChangeBetweenAandB.CalculationB == calculation.TemplateCalculationId)))
                        {
                            AddFailure(context, "Calculation",
                                       $"Calculation with name '{calculation.Name}' and id : '{calculation.TemplateCalculationId}' " +
                                       $"has CalculationB with TemplateCalculationId {calculation.PercentageChangeBetweenAandB.CalculationB} " +
                                       "that contains a PercentageChangeBetweenAandB referring back to this calculation.");
                        }
                    }

                    if (calculation.PercentageChangeBetweenAandB.CalculationA == calculation.PercentageChangeBetweenAandB.CalculationB)
                    {
                        AddFailure(context, "Calculation",
                                   $"Calculation with name '{calculation.Name}' and id : '{calculation.TemplateCalculationId}' " +
                                   "has the same PercentageChangeBetweenAandB value for CalculationA and CalculationB.");
                    }

                    if (calculation.PercentageChangeBetweenAandB.CalculationA == calculation.TemplateCalculationId)
                    {
                        AddFailure(context, "Calculation",
                                   $"Calculation with name '{calculation.Name}' and id : '{calculation.TemplateCalculationId}' " +
                                   "has PercentageChangeBetweenAandB CalculationA referring to its own TemplateCalculationId.");
                    }

                    if (calculation.PercentageChangeBetweenAandB.CalculationB == calculation.TemplateCalculationId)
                    {
                        AddFailure(context, "Calculation",
                                   $"Calculation with name '{calculation.Name}' and id : '{calculation.TemplateCalculationId}' " +
                                   "has PercentageChangeBetweenAandB CalculationB referring to its own TemplateCalculationId.");
                    }
                }
            }
        }
Пример #11
0
        private void CheckForClonesWithDifferentValues(CustomContext context, SchemaJsonCalculation calculation)
        {
            var calculationClones = _flattenedCalculations
                                    .Where(x => x.TemplateCalculationId == calculation.TemplateCalculationId && x.Id != calculation.Id);

            foreach (var clone in calculationClones)
            {
                CheckForNonMatchingChildren(context, calculation, clone);

                if (!clone.Name.Trim().Equals(calculation.Name.Trim(), StringComparison.OrdinalIgnoreCase))
                {
                    AddFailure(context, "Calculation",
                               $"Calculation with id '{calculation.TemplateCalculationId}' " +
                               $"occurs more than once in the template but with different names ['{calculation.Name}' vs '{clone.Name}']");
                }

                if (clone.AggregationType != calculation.AggregationType)
                {
                    AddFailure(context, "Calculation",
                               $"Calculation with id '{calculation.TemplateCalculationId}' " +
                               "occurs more than once in the template but with different aggregation types " +
                               $"['{calculation.AggregationType}' vs '{clone.AggregationType}']");
                }

                if (clone.Type != calculation.Type)
                {
                    AddFailure(context, "Calculation",
                               $"Calculation with id '{calculation.TemplateCalculationId}' " +
                               "occurs more than once in the template but with different calculation types " +
                               $"['{calculation.Type}' vs '{clone.Type}']");
                }

                if (clone.ValueFormat != calculation.ValueFormat)
                {
                    AddFailure(context, "Calculation",
                               $"Calculation with id '{calculation.TemplateCalculationId}' " +
                               "occurs more than once in the template but with different value formats " +
                               $"['{calculation.ValueFormat}' vs '{clone.ValueFormat}']");
                }

                if (clone.FormulaText != calculation.FormulaText)
                {
                    AddFailure(context, "Calculation",
                               $"Calculation with id '{calculation.TemplateCalculationId}' " +
                               "occurs more than once in the template but with different formula texts " +
                               $"['{calculation.FormulaText}' vs '{clone.FormulaText}']");
                }

                switch (calculation.AggregationType)
                {
                case AggregationType.PercentageChangeBetweenAandB
                    when clone.PercentageChangeBetweenAandB.CalculationA != calculation.PercentageChangeBetweenAandB.CalculationA ||
                    clone.PercentageChangeBetweenAandB.CalculationB != calculation.PercentageChangeBetweenAandB.CalculationB ||
                    clone.PercentageChangeBetweenAandB.CalculationAggregationType !=
                    calculation.PercentageChangeBetweenAandB.CalculationAggregationType:
                    AddFailure(context, "Calculation",
                               $"Calculation with id '{calculation.TemplateCalculationId}' " +
                               "occurs more than once in the template but with different values for percentage change between A and B");
                    break;

                case AggregationType.GroupRate
                    when clone.GroupRate?.Numerator != calculation.GroupRate?.Numerator ||
                    clone.GroupRate?.Denominator != calculation.GroupRate?.Denominator:
                    AddFailure(context, "Calculation",
                               $"Calculation with id '{calculation.TemplateCalculationId}' " +
                               "occurs more than once in the template but with different group rates");
                    break;
                }

                if (!clone.AllowedEnumTypeValues.IsNullOrEmpty() && !clone.AllowedEnumTypeValues.SequenceEqual(calculation.AllowedEnumTypeValues))
                {
                    AddFailure(context, "Calculation",
                               $"Calculation with id '{calculation.TemplateCalculationId}' " +
                               "occurs more than once in the template but with different allowed enum type values " +
                               $"['{calculation.AllowedEnumTypeValues}' vs '{clone.AllowedEnumTypeValues}']");
                }
            }
        }