public void When_StageSplitIs_Zero_Or_One_ShouldNotThrowException(decimal split)
            {
                // Arrange
                var rule = new PgVendorRuleDefinition
                {
                    Splits = new[]
                    {
                        new PgVendorRuleSplit
                        {
                            CostTotalType = Constants.CostSection.CostTotal,
                            StageSplits   = new Dictionary <string, decimal?>
                            {
                                { CostStages.FinalActual.ToString(), split }
                            }
                        }
                    }
                };
                var ruleStr  = JsonConvert.SerializeObject(rule);
                var ruleMode = new VendorRuleModel
                {
                    Name       = "Vendor payment rule 1",
                    Definition = JsonConvert.DeserializeObject <Dictionary <string, dynamic> >(ruleStr)
                };
                var vendor = new Vendor {
                    Name = "Vendor 1"
                };

                // Act, Assert
                _pgVendorRuleBuilder
                .Awaiting(b => b.ValidateAndGetVendorRules(ruleMode, vendor, It.IsAny <Guid>()))
                .ShouldNotThrow <Exception>();
            }
예제 #2
0
        private async Task <VendorRule> GetVendorRule(VendorRuleModel ruleModel, string ruleDefinition, Guid userId, RuleType ruleType, Vendor vendor)
        {
            var criterion = ruleModel.Criteria != null
                ? new RuleCriterion
            {
                Operator = ExpressionType.And.ToString(),
                Children = await GetRuleCriteria(ruleModel.Criteria)
            }
                : null;

            var ruleEntity = new Rule(userId)
            {
                Name       = $"{vendor.Name}_{ruleType}_{ruleModel.Name}",
                Criterion  = criterion,
                Definition = ruleDefinition,
                Type       = ruleType
            };

            var vendorRule = new VendorRule
            {
                Name = ruleModel.Name,
                Rule = ruleEntity
            };

            return(vendorRule);
        }
            public void ThrowException_When_CriterionIsSelectAndValueIsInvalid2()
            {
                // Arrange
                var costTotalType = "Anything else";

                var rule = new PgVendorRuleDefinition
                {
                    Splits = new[]
                    {
                        new PgVendorRuleSplit
                        {
                            CostTotalType = costTotalType,
                            StageSplits   = new Dictionary <string, decimal?>()
                        }
                    }
                };
                var ruleStr  = JsonConvert.SerializeObject(rule);
                var ruleMode = new VendorRuleModel
                {
                    Name       = "Vendor payment rule 1",
                    Definition = JsonConvert.DeserializeObject <Dictionary <string, dynamic> >(ruleStr)
                };
                var vendor = new Vendor {
                    Name = "Vendor 1"
                };

                // Act, Assert
                _pgVendorRuleBuilder
                .Awaiting(b => b.ValidateAndGetVendorRules(ruleMode, vendor, It.IsAny <Guid>()))
                .ShouldThrow <Exception>()
                .WithMessage($"Unsupported Cost Total Type {costTotalType}");
            }
            public void ThrowException_When_CriterionNameIsInvalid()
            {
                // Arrange
                const string criteriaName = "unsupported criterion";
                var          rule         = new PgVendorRuleDefinition
                {
                    Splits = new PgVendorRuleSplit[0]
                };
                var ruleStr  = JsonConvert.SerializeObject(rule);
                var ruleMode = new VendorRuleModel
                {
                    Name       = "Vendor payment rule 1",
                    Definition = JsonConvert.DeserializeObject <Dictionary <string, dynamic> >(ruleStr),
                    Criteria   = new Dictionary <string, CriterionValueModel>
                    {
                        { criteriaName, new CriterionValueModel() }
                    }
                };
                var vendor = new Vendor {
                    Name = "Vendor 1"
                };

                MockCriteria();

                // Act
                // Assert
                _pgVendorRuleBuilder
                .Awaiting(b => b.ValidateAndGetVendorRules(ruleMode, vendor, It.IsAny <Guid>()))
                .ShouldThrow <Exception>()
                .WithMessage($"Unsupported criterion {criteriaName}");
            }
            public void ThrowException_When_CriterionIsSelectAndValueIsInvalid()
            {
                // Arrange
                const string validCriteriaName = nameof(Constants.DictionaryNames.ContentType);
                const string wrongValue        = "not existing value";
                var          rule = new PgVendorRuleDefinition
                {
                    Splits = new PgVendorRuleSplit[0]
                };
                var ruleStr  = JsonConvert.SerializeObject(rule);
                var ruleMode = new VendorRuleModel
                {
                    Name       = "Vendor payment rule 1",
                    Definition = JsonConvert.DeserializeObject <Dictionary <string, dynamic> >(ruleStr),
                    Criteria   = new Dictionary <string, CriterionValueModel>
                    {
                        { validCriteriaName, new CriterionValueModel {
                              Value = wrongValue
                          } }
                    }
                };
                var vendor = new Vendor {
                    Name = "Vendor 1"
                };

                MockCriteria();

                // Act
                // Assert
                _pgVendorRuleBuilder
                .Awaiting(b => b.ValidateAndGetVendorRules(ruleMode, vendor, It.IsAny <Guid>()))
                .ShouldThrow <Exception>()
                .WithMessage($"Unsupported value {wrongValue} of {validCriteriaName} criterion");
            }
            public async Task DetailedSplit_When_SingleSplit_And_CostsTotal_ShouldBeFalse()
            {
                // Arrange
                var rule = new PgVendorRuleDefinition
                {
                    Splits = new[]
                    {
                        new PgVendorRuleSplit
                        {
                            CostTotalType = Constants.CostSection.CostTotal,
                            StageSplits   = new Dictionary <string, decimal?>
                            {
                                { CostStages.FinalActual.ToString(), (decimal)1.0 }
                            }
                        }
                    }
                };
                var ruleStr  = JsonConvert.SerializeObject(rule);
                var ruleMode = new VendorRuleModel
                {
                    Name       = "Vendor payment rule 1",
                    Definition = JsonConvert.DeserializeObject <Dictionary <string, dynamic> >(ruleStr)
                };
                var vendor = new Vendor {
                    Name = "Vendor 1"
                };

                // Act
                var result = await _pgVendorRuleBuilder.ValidateAndGetVendorRules(ruleMode, vendor, It.IsAny <Guid>());

                var parsedResult = JsonConvert.DeserializeObject <PgPaymentRuleDefinition>(result.First().Rule.Definition);

                // Assert
                parsedResult.DetailedSplit.Should().BeFalse();
            }
            public async Task Always_Should_MapStageSplitsCorrectly()
            {
                // Arrange
                const decimal aipeSplit = 0.1m;
                const decimal oeSplit   = 0.2m;
                const decimal fpSplit   = 0.3m;
                const decimal faSplit   = 1.0m;

                var rule = new PgVendorRuleDefinition
                {
                    Splits = new[]
                    {
                        new PgVendorRuleSplit
                        {
                            CostTotalType = Constants.CostSection.TargetBudgetTotal,
                            StageSplits   = new Dictionary <string, decimal?>
                            {
                                { CostStages.Aipe.ToString(), aipeSplit },
                                { CostStages.OriginalEstimate.ToString(), oeSplit },
                                { CostStages.FirstPresentation.ToString(), fpSplit },
                                { CostStages.FinalActual.ToString(), faSplit }
                            }
                        }
                    }
                };
                var ruleStr  = JsonConvert.SerializeObject(rule);
                var ruleMode = new VendorRuleModel
                {
                    Name       = "Vendor payment rule 1",
                    Definition = JsonConvert.DeserializeObject <Dictionary <string, dynamic> >(ruleStr)
                };
                var vendor = new Vendor {
                    Name = "Vendor 1"
                };

                // Act
                var result = await _pgVendorRuleBuilder.ValidateAndGetVendorRules(ruleMode, vendor, It.IsAny <Guid>());

                var parsedResult = JsonConvert.DeserializeObject <PgPaymentRuleDefinition>(result.First().Rule.Definition);

                // Assert
                parsedResult.Splits.Should().HaveCount(1);
                parsedResult.Splits[0].AIPESplit.Should().Be(aipeSplit);
                parsedResult.Splits[0].OESplit.Should().Be(oeSplit);
                parsedResult.Splits[0].FPSplit.Should().Be(fpSplit);
                parsedResult.Splits[0].FASplit.Should().Be(faSplit);
            }
예제 #8
0
        public async Task <List <VendorRule> > ValidateAndGetVendorRules(VendorRuleModel ruleModel, Vendor vendor, Guid userId)
        {
            var vendorRules = new List <VendorRule>();

            var definition            = JsonConvert.SerializeObject(ruleModel.Definition);
            var paymentRuleDefinition = GetPaymentRuleDefinition(definition);

            vendorRules.Add(await GetVendorRule(ruleModel, paymentRuleDefinition, userId, RuleType.VendorPayment, vendor));

            if (ruleModel.SkipFirstPresentation)
            {
                var stageRuleDefinition = await GetSkipFirstPresentationRule();

                vendorRules.Add(await GetVendorRule(ruleModel, stageRuleDefinition, userId, RuleType.VendorStage, vendor));
            }

            return(vendorRules);
        }
            public async Task SkipFirstStagePresentation_When_SkipFirstPresentation_ShouldAddSkipFirstPresentationStageRule()
            {
                // Arrange
                var rule = new PgVendorRuleDefinition
                {
                    Splits = new PgVendorRuleSplit[0]
                };
                var ruleStr  = JsonConvert.SerializeObject(rule);
                var ruleMode = new VendorRuleModel
                {
                    Name                  = "Vendor payment rule 1",
                    Definition            = JsonConvert.DeserializeObject <Dictionary <string, dynamic> >(ruleStr),
                    SkipFirstPresentation = true
                };
                var vendor = new Vendor {
                    Name = "Vendor 1"
                };
                var skipFirstPresentationRule = new Rule
                {
                    Name       = Constants.Rules.Stage.SkipFirstPresentation,
                    Type       = RuleType.Stage,
                    Definition = JsonConvert.SerializeObject(new PgStageRuleDefinition())
                };

                _efContext.Rule.Add(skipFirstPresentationRule);
                _efContext.SaveChanges();

                // Act
                var vendorRules = await _pgVendorRuleBuilder.ValidateAndGetVendorRules(ruleMode, vendor, It.IsAny <Guid>());

                var parsedResults = vendorRules.Select(r =>
                                                       JsonConvert.DeserializeObject <PgPaymentRuleDefinition>(r.Rule.Definition))
                                    .ToArray();

                //Assert
                parsedResults.Should().HaveCount(2);
                vendorRules.Count(r => r.Rule.Type == RuleType.VendorStage).Should().Be(1);
                vendorRules.Count(r => r.Rule.Type == RuleType.VendorPayment).Should().Be(1);
                var stageRule = vendorRules.First(vr => vr.Rule.Type == RuleType.VendorStage);

                stageRule.Rule.Definition.Should().Be(skipFirstPresentationRule.Definition);
            }
            public async Task When_StageSplitIsNotListedInSplits_Should_DefaultSplitToZero()
            {
                // Arrange
                const decimal faSplit = 1.0m;

                var rule = new PgVendorRuleDefinition
                {
                    Splits = new[]
                    {
                        new PgVendorRuleSplit
                        {
                            CostTotalType = Constants.CostSection.TargetBudgetTotal,
                            StageSplits   = new Dictionary <string, decimal?>
                            {
                                { CostStages.FinalActual.ToString(), faSplit }
                            }
                        }
                    }
                };
                var ruleStr  = JsonConvert.SerializeObject(rule);
                var ruleMode = new VendorRuleModel
                {
                    Name       = "Vendor payment rule 1",
                    Definition = JsonConvert.DeserializeObject <Dictionary <string, dynamic> >(ruleStr)
                };
                var vendor = new Vendor {
                    Name = "Vendor 1"
                };

                // Act
                var result = await _pgVendorRuleBuilder.ValidateAndGetVendorRules(ruleMode, vendor, It.IsAny <Guid>());

                var parsedResult = JsonConvert.DeserializeObject <PgPaymentRuleDefinition>(result.First().Rule.Definition);

                // Assert
                parsedResult.Splits.Should().HaveCount(1);
                parsedResult.Splits[0].AIPESplit.Should().Be(0m);
                parsedResult.Splits[0].OESplit.Should().Be(0m);
                parsedResult.Splits[0].FPSplit.Should().Be(0m);
                parsedResult.Splits[0].FASplit.Should().Be(faSplit);
            }
예제 #11
0
        public async Task <List <VendorCategoryModel> > GetVendorCategoryModels(List <VendorCategory> vendorCategories)
        {
            if (vendorCategories == null)
            {
                throw new ArgumentException(nameof(vendorCategories));
            }

            var vendorCategoryModels = new List <VendorCategoryModel>();

            foreach (var category in vendorCategories)
            {
                var categoryModel = _mapper.Map <VendorCategoryModel>(category);

                var vendorRulesList = category.VendorCategoryRules ?? new List <VendorRule>(category.VendorCategoryRules);
                if (vendorRulesList.Count == 0)
                {
                    vendorCategoryModels.Add(categoryModel);
                    continue;
                }

                var vendorCriteria = (await GetVendorCriteria()).ToDictionary(vs => vs.FieldName, vs => vs);

                categoryModel.PaymentRules = vendorRulesList.GroupBy(r => r.Name).Select(g =>
                {
                    var vr = g.First(r => r.Rule.Type == RuleType.VendorPayment);

                    var vendor = new VendorRuleModel
                    {
                        Id         = vr.Id,
                        Name       = vr.Name,
                        Criteria   = BuildVendorCriterial(vr.Rule.Criterion?.Children, vendorCriteria, vr).ToDictionary(c => c.FieldName, c => c),
                        Definition = vr.Rule.Type == RuleType.VendorPayment
                                ? ParseRuleDefinition(vr.Rule.Definition)
                                : null
                    };
                    if (g.Any(r => r.Rule.Type == RuleType.VendorStage))
                    {
                        vendor.SkipFirstPresentation = true;
                    }

                    return(vendor);
                })
                                             .ToArray();

                foreach (var fieldName in vendorCriteria.Keys)
                {
                    foreach (var model in categoryModel.PaymentRules)
                    {
                        if (!model.Criteria.ContainsKey(fieldName))
                        {
                            model.Criteria.Add(fieldName,
                                               new CriterionValueModel
                            {
                                FieldName = fieldName,
                                Value     = AllOption,
                                Operator  = ExpressionType.Equal.ToString(),
                                Text      = AllOption
                            });
                        }
                    }
                }
                vendorCategoryModels.Add(categoryModel);
            }

            return(vendorCategoryModels);
        }