//Percentage and FixedAmount have two variations that sets them over upper limit and calculated should be equal to upper limit
        public void CalculatedOverUpperLimitMultipleVariations()
        {
            ConfigurationServiceMock       configurationService = new ConfigurationServiceMock();
            PriceCalculationDMNServiceMock priceCalCService     = new PriceCalculationDMNServiceMock(configurationService);
            MarketRatesServiceMock         marketRatesService   = new MarketRatesServiceMock();
            var          OfferPriceCalculation = new OfferPriceCalculation(priceCalCService, marketRatesService, configurationService, null);
            FeeCondition regularFee            = new FeeCondition
            {
                Percentage  = (decimal)0.1,
                FixedAmount = new Currency {
                    Amount = 20, Code = "EUR"
                },
                LowerLimit = new Currency {
                    Amount = 20, Code = "EUR"
                },
                UpperLimit = new Currency {
                    Amount = 200, Code = "EUR"
                },
                VariationsDefinitionDMN = "product/price-variations/multiple-fee-var-over-range.dmn",
                PercentageLowerLimit    = (decimal)0.05,
                PercentageUpperLimit    = 1,
                Title         = "Origination-fee1",
                EffectiveDate = DateTime.Now.AddDays(-1),
                Currencies    = new List <string> {
                    "RSD", "EUR"
                }
            };

            ProductConditions conditions = new ProductConditions
            {
                Fees = new List <FeeCondition> {
                    regularFee
                },
                InterestRates = new List <InterestRateCondition> {
                }
            };
            Application application                = Utility.GetApplication(conditions);
            var         arrangementRequest         = application.ArrangementRequests[0] as TermLoanRequest;
            var         priceCalculationConditions = Utility.GetPriceCalculationParameterFromTermLoanRequest(arrangementRequest);


            var result     = OfferPriceCalculation.CalculatePrice(application, arrangementRequest);
            var resultFees = result.Result.Conditions.Fees[0];
            var variation  = result.Result.Conditions.Fees[0].Variations;

            Assert.Equal("2", variation.Count.ToString());

            var variationOne = variation[0];
            var variationTwo = variation[1];

            Assert.Equal("RanToCompletion", result.Status.ToString());
            Assert.Equal(1, resultFees.CalculatedPercentage);
            Assert.Equal((decimal)0.4, variationOne.Percentage);
            Assert.Equal((decimal)0.6, variationTwo.Percentage);
            Assert.Equal("product/price-variations/multiple-fee-var-over-range.dmn", resultFees.VariationsDefinitionDMN);
        }
        private FeeCondition SolveFeeCondition(FeeCondition fee)
        {
            if (fee != null)
            {
                FeeVariation feeVariation = SumFeeVariations(fee.Variations);
                fee.CalculatedFixedAmount = (fee.FixedAmount?.Amount ?? 0) + feeVariation.FixedAmount;
                fee.CalculatedLowerLimit  = (fee.LowerLimit?.Amount ?? 0) + feeVariation.LowerLimit;
                fee.CalculatedUpperLimit  = (fee.UpperLimit?.Amount ?? 0) + feeVariation.UpperLimit;
                fee.CalculatedPercentage  = fee.Percentage + feeVariation.Percentage;

                if (fee.PercentageLowerLimit.HasValue && fee.PercentageLowerLimit.Value > fee.CalculatedPercentage)
                {
                    fee.CalculatedPercentage        = fee.PercentageLowerLimit.Value;
                    fee.PercentageLowerLimitApplied = true;
                }
                else if (fee.PercentageUpperLimit.HasValue && fee.CalculatedPercentage > fee.PercentageUpperLimit.Value)
                {
                    fee.CalculatedPercentage        = fee.PercentageUpperLimit.Value;
                    fee.PercentageUpperLimitApplied = true;
                }
            }
            return(fee);
        }
        //Percentage and FixedAmount have a variation that sets them to near lower limit but still above
        public void CalculatedNearLowerLimit()
        {
            ConfigurationServiceMock       configurationService = new ConfigurationServiceMock();
            PriceCalculationDMNServiceMock priceCalCService     = new PriceCalculationDMNServiceMock(configurationService);
            MarketRatesServiceMock         marketRatesService   = new MarketRatesServiceMock();
            var          OfferPriceCalculation = new OfferPriceCalculation(priceCalCService, marketRatesService, configurationService, null);
            FeeCondition regularFee            = new FeeCondition
            {
                //Samo % se testira za sada jer trenutno nema za fixedAmount
                //Samo varijacije uticu na PercentageKind = FeeConditionKinds.OriginationFee,
                Percentage  = (decimal)0.1,
                FixedAmount = new Currency {
                    Amount = 200, Code = "EUR"
                },
                LowerLimit = new Currency {
                    Amount = 20, Code = "EUR"
                },
                UpperLimit = new Currency {
                    Amount = 200, Code = "EUR"
                },
                VariationsDefinitionDMN = "product/price-variations/fee-in-range-lower.dmn",
                PercentageLowerLimit    = (decimal)0.01,
                PercentageUpperLimit    = 1,
                Title         = "Origination-fee1",
                EffectiveDate = DateTime.Now.AddDays(-1),
                Currencies    = new List <string> {
                    "RSD", "EUR"
                }
            };

            ProductConditions conditions = new ProductConditions
            {
                Fees = new List <FeeCondition> {
                    regularFee
                },
                InterestRates = new List <InterestRateCondition> {
                }
            };

            Application application                = Utility.GetApplication(conditions);
            var         arrangementRequest         = application.ArrangementRequests[0] as TermLoanRequest;
            var         priceCalculationConditions = Utility.GetPriceCalculationParameterFromTermLoanRequest(arrangementRequest);


            var result = OfferPriceCalculation.CalculatePrice(application, arrangementRequest);

            //Basic assertions
            Assert.Equal("RanToCompletion", result.Status.ToString());

            Assert.Single(result.Result.Conditions.Fees);
            var resultFees = result.Result.Conditions.Fees[0];

            Assert.Single(resultFees.Variations);
            var variation = resultFees.Variations[0];


            //Asserting input
            Assert.Equal(200, resultFees.FixedAmount.Amount);
            Assert.Equal((decimal)0.1, resultFees.Percentage);

            //Asserting output
            Assert.Equal("product/price-variations/fee-in-range-lower.dmn", resultFees.VariationsDefinitionDMN);
            Assert.Equal((decimal)0.02, resultFees.CalculatedPercentage);
            Assert.Equal((decimal) - 0.08, variation.Percentage);
            Assert.Equal(21, resultFees.CalculatedFixedAmount);
            Assert.Equal(-179, variation.FixedAmount);
        }
        public void TwoInterestRatesOneUsed()
        {
            ConfigurationServiceMock       configurationService = new ConfigurationServiceMock();
            PriceCalculationDMNServiceMock priceCalCService     = new PriceCalculationDMNServiceMock(configurationService);
            MarketRatesServiceMock         marketRatesService   = new MarketRatesServiceMock();
            var OfferPriceCalculation = new OfferPriceCalculation(priceCalCService, marketRatesService, configurationService, null);

            /*VariationsDefinition (fee.variationsDefinition) utice na fee.percentage (percentage + varijacije)
             * fixedAmount moze da seta u okviru definisanih granica (Upper/LowerLimitAmount ili percentage)
             */
            //moze da postoji samo jedan origination fee
            FeeCondition regularFee = new FeeCondition
            {
                Kind               = FeeConditionKinds.OriginationFee,
                ServiceCode        = "",
                ServiceDescription = "",
                Percentage         = (decimal)0.2,
                FixedAmount        = new Currency {
                    Amount = 200, Code = "RSD"
                },
                LowerLimit = new Currency {
                    Amount = 200, Code = "RSD"
                },
                UpperLimit = new Currency {
                    Amount = 4000, Code = "RSD"
                },
                PercentageLowerLimit = (decimal)0.01,
                PercentageUpperLimit = 1,
                Title         = "Origination-fee1",
                EffectiveDate = DateTime.Now.AddDays(-1),
                Currencies    = new List <string> {
                    "RSD", "EUR"
                }
            };
            //SpreadRateValue + BaseRateValue + SumaVarijacija = interestRate.CalculatedRate
            //Vazi za svaki interest rate
            //Samo jedan RegularInterest moze biti na proizvodu i napr je vezan samo za njegov CalculatedRate
            InterestRateCondition regularInterestEuribor = new InterestRateCondition
            {
                //market-rates api ima bazne vrednosti za interest rates - odavde uzeti primere
                //Regular interest moze da bude definisan posebno za svaku valutu
                Kind = InterestRateKinds.RegularInterest,
                Rate = new InterestRate
                {
                    BaseRateId      = "EURIBOR-3M",
                    SpreadRateValue = 10
                },
                Title      = "regular-interest",
                Currencies = new List <string> {
                    "EUR"
                }
            };

            InterestRateCondition regularInterestBelibor = new InterestRateCondition
            {
                //SpreadRateValue je fiksni deo kamatne stope
                //Base rate id definise prema cemu se gleda promenljivi deo (baseRateBalue) kamatne stope
                //Obuhvati da nema stopu
                //IsFixed
                Kind = InterestRateKinds.RegularInterest,
                Rate = new InterestRate
                {
                    BaseRateId      = "BELIBOR-3M",
                    SpreadRateValue = 12
                },
                Title      = "regular-interest",
                Currencies = new List <string> {
                    "RSD"
                }
            };

            ProductConditions conditions = new ProductConditions {
                Fees = new List <FeeCondition> {
                    regularFee
                },
                InterestRates = new List <InterestRateCondition> {
                    regularInterestEuribor, regularInterestBelibor
                }
            };
            Application application                = Utility.GetApplication(conditions);
            var         arrangementRequest         = application.ArrangementRequests[0] as TermLoanRequest;
            var         priceCalculationConditions = Utility.GetPriceCalculationParameterFromTermLoanRequest(arrangementRequest);


            var result         = OfferPriceCalculation.CalculatePrice(application, arrangementRequest);
            var resultFees     = result.Result.Conditions.Fees[0];
            var resultInterest = result.Result.Conditions.InterestRates[0];

            Assert.Equal("RanToCompletion", result.Status.ToString());
            Assert.Empty(resultFees.Variations);
            Assert.Equal((decimal)0.2, resultFees.CalculatedPercentage);
            Assert.Equal(200, resultFees.CalculatedFixedAmount);
            Assert.Null(resultFees.VariationsDefinitionDMN);

            Assert.Equal("BELIBOR-3M", resultInterest.Rate.BaseRateId);
            Assert.Equal((decimal)9.5, resultInterest.CalculatedRate);
            Assert.Equal((decimal) - 2.5, resultInterest.Rate.BaseRateValue);
            Assert.Equal((decimal)12.0, resultInterest.Rate.SpreadRateValue);
            //C# won't let this be asserted in any other way
            Assert.Equal("0", resultInterest.Variations.Count.ToString());

            Assert.Empty(resultInterest.Variations);
            Assert.Equal(0, resultInterest.CalculatedLowerLimit);
            Assert.Equal(100, resultInterest.CalculatedUpperLimit);
        }
        public void MultipleOriginationFeesBothCalculated()
        {
            ConfigurationServiceMock       configurationService = new ConfigurationServiceMock();
            PriceCalculationDMNServiceMock priceCalCService     = new PriceCalculationDMNServiceMock(configurationService);
            MarketRatesServiceMock         marketRatesService   = new MarketRatesServiceMock();
            var          OfferPriceCalculation = new OfferPriceCalculation(priceCalCService, marketRatesService, configurationService, null);
            FeeCondition regularFee            = new FeeCondition
            {
                Kind               = FeeConditionKinds.OriginationFee,
                ServiceCode        = "",
                ServiceDescription = "",
                Percentage         = (decimal)0.2,
                FixedAmount        = new Currency {
                    Amount = 200, Code = "RSD"
                },
                LowerLimit = new Currency {
                    Amount = 200, Code = "RSD"
                },
                UpperLimit = new Currency {
                    Amount = 4000, Code = "RSD"
                },
                PercentageLowerLimit = (decimal)0.01,
                PercentageUpperLimit = 1,
                Title         = "Origination-fee1",
                EffectiveDate = DateTime.Now.AddDays(-1),
                Currencies    = new List <string> {
                    "RSD", "EUR"
                }
            };

            FeeCondition regularFee2 = new FeeCondition
            {
                Kind               = FeeConditionKinds.OriginationFee,
                ServiceCode        = "",
                ServiceDescription = "",
                Percentage         = (decimal)0.3,
                FixedAmount        = new Currency {
                    Amount = 300, Code = "RSD"
                },
                LowerLimit = new Currency {
                    Amount = 200, Code = "RSD"
                },
                UpperLimit = new Currency {
                    Amount = 4000, Code = "RSD"
                },
                PercentageLowerLimit = (decimal)0.01,
                PercentageUpperLimit = 1,
                Title         = "Origination-fee2",
                EffectiveDate = DateTime.Now.AddDays(-1),
                Currencies    = new List <string> {
                    "RSD", "EUR"
                }
            };

            ProductConditions conditions = new ProductConditions
            {
                Fees = new List <FeeCondition> {
                    regularFee
                },
                InterestRates = new List <InterestRateCondition> {
                }
            };
            Application application                = Utility.GetApplication(conditions);
            var         arrangementRequest         = application.ArrangementRequests[0] as TermLoanRequest;
            var         priceCalculationConditions = Utility.GetPriceCalculationParameterFromTermLoanRequest(arrangementRequest);


            var result = OfferPriceCalculation.CalculatePrice(application, arrangementRequest);

            Assert.Equal("RanToCompletion", result.Status.ToString());
            var resultFees = result.Result.Conditions.Fees;

            Assert.Equal("2", resultFees.Count.ToString());
            var resultFeeOne = resultFees[0];

            Assert.Empty(resultFeeOne.Variations);
            Assert.Equal((decimal)0.2, resultFeeOne.CalculatedPercentage);
            Assert.Equal(200, resultFeeOne.CalculatedFixedAmount);
            Assert.Null(resultFeeOne.VariationsDefinitionDMN);

            var resultFeeTwo = resultFees[1];

            Assert.Empty(resultFeeTwo.Variations);
            Assert.Equal((decimal)0.3, resultFeeTwo.CalculatedPercentage);
            Assert.Equal(300, resultFeeTwo.CalculatedFixedAmount);
            Assert.Null(resultFeeTwo.VariationsDefinitionDMN);
        }
        //Arrangement Request is set to EUR
        //There are no defined variations - Application data does not matter
        //There are two fees, both accounted because they're in the same currency
        public void TwoInterestRatesDiferentKind()
        {
            ConfigurationServiceMock       configurationService = new ConfigurationServiceMock();
            PriceCalculationDMNServiceMock priceCalCService     = new PriceCalculationDMNServiceMock(configurationService);
            MarketRatesServiceMock         marketRatesService   = new MarketRatesServiceMock();
            var          OfferPriceCalculation = new OfferPriceCalculation(priceCalCService, marketRatesService, configurationService, null);
            FeeCondition regularFee            = new FeeCondition
            {
                //Samo % se testira za sada jer trenutno nema za fixedAmount
                //Samo varijacije uticu na Percentage
                Kind        = FeeConditionKinds.OriginationFee,
                Percentage  = (decimal)0.2,
                FixedAmount = new Currency {
                    Amount = 200, Code = "EUR"
                },
                LowerLimit = new Currency {
                    Amount = 200, Code = "EUR"
                },
                UpperLimit = new Currency {
                    Amount = 4000, Code = "EUR"
                },
                PercentageLowerLimit = (decimal)0.01,
                PercentageUpperLimit = 1,
                Title         = "Origination-fee1",
                EffectiveDate = DateTime.Now.AddDays(-1),
                Currencies    = new List <string> {
                    "RSD", "EUR"
                }
            };

            InterestRateCondition regularInterestEuribor = new InterestRateCondition
            {
                Kind = InterestRateKinds.RegularInterest,
                Rate = new InterestRate
                {
                    BaseRateId      = "EURIBOR-3M",
                    SpreadRateValue = 10
                },
                Title      = "regular-interest",
                Currencies = new List <string> {
                    "EUR"
                }
            };

            InterestRateCondition earlyWithdrawalInterest = new InterestRateCondition
            {
                Kind = InterestRateKinds.EarlyWithdrawalInterest,
                Rate = new InterestRate
                {
                    BaseRateId      = "EARLY-EUR",
                    SpreadRateValue = 2
                },
                Title      = "early-withdrawal-interest",
                Currencies = new List <string> {
                    "EUR"
                }
            };

            ProductConditions conditions = new ProductConditions
            {
                Fees = new List <FeeCondition> {
                    regularFee
                },
                InterestRates = new List <InterestRateCondition> {
                    regularInterestEuribor, earlyWithdrawalInterest
                }
            };

            Application application                = Utility.GetApplication(conditions);
            var         arrangementRequest         = application.ArrangementRequests[0] as TermLoanRequest;
            var         priceCalculationConditions = Utility.GetPriceCalculationParameterFromTermLoanRequest(arrangementRequest);


            var result = OfferPriceCalculation.CalculatePrice(application, arrangementRequest);

            Assert.Single(result.Result.Conditions.Fees);
            Assert.Equal("RanToCompletion", result.Status.ToString());

            var resultInterest = result.Result.Conditions.InterestRates[0];
            var resultEarlyWithdrawalInterest = result.Result.Conditions.InterestRates[1];

            Assert.Equal("EURIBOR-3M", resultInterest.Rate.BaseRateId);
            Assert.Equal((decimal)8.5, resultInterest.CalculatedRate);
            Assert.Equal((decimal) - 1.5, resultInterest.Rate.BaseRateValue);
            Assert.Equal((decimal)10.0, resultInterest.Rate.SpreadRateValue);
            //C# won't let this be asserted in any other way
            Assert.Equal("0", resultInterest.Variations.Count.ToString());

            Assert.Equal("EARLY-EUR", resultEarlyWithdrawalInterest.Rate.BaseRateId);
            Assert.Equal((decimal)3.5, resultEarlyWithdrawalInterest.CalculatedRate);
            Assert.Equal((decimal)1.5, resultEarlyWithdrawalInterest.Rate.BaseRateValue);
            Assert.Equal((decimal)2.0, resultEarlyWithdrawalInterest.Rate.SpreadRateValue);

            Assert.Equal(0, resultInterest.CalculatedLowerLimit);
            Assert.Equal(100, resultInterest.CalculatedUpperLimit);
        }
        private FeeCondition ResolveFeeBenefits(PriceCalculationParameters calculationParameters, FeeCondition fee)
        {
            var feeKind = ((EnumMemberAttribute[])(typeof(FeeConditionKind)).GetField(fee.Kind.ToString())
                           .GetCustomAttributes(typeof(EnumMemberAttribute), true))?.FirstOrDefault()?.Value;

            fee.Variations = fee.Variations ?? new List <FeeVariation>();
            fee.Variations = fee.Variations.Where(nv => nv.Origin != PriceVariationOrigins.Campaign).ToList();
            if (calculationParameters.Campaign?.Benefits != null)
            {
                var benefitsForFee = calculationParameters.Campaign.Benefits.Where(b => b.Kind == feeKind)?.ToList();
                if (benefitsForFee != null && benefitsForFee.Count() > 0)
                {
                    foreach (var benefit in benefitsForFee)
                    {
                        fee.Variations.Add(new FeeVariation
                        {
                            BenefitId            = benefit.Code,
                            BenefitSourceId      = calculationParameters.Campaign.CampaignCode,
                            Origin               = PriceVariationOrigins.Campaign,
                            Percentage           = benefit.Value,
                            VariationDescription = benefit.Description,
                            VariationGroup       = calculationParameters.Campaign.Description
                        });
                    }
                }
            }
            return(fee);
        }
        private FeeCondition ResolveFeeOptions(PriceCalculationParameters calculationParameters, FeeCondition fee)
        {
            var feeKind = ((EnumMemberAttribute[])(typeof(FeeConditionKind)).GetField(fee.Kind.ToString())
                           .GetCustomAttributes(typeof(EnumMemberAttribute), true))?.FirstOrDefault()?.Value;

            fee.Variations = fee.Variations ?? new List <FeeVariation>();
            fee.Variations = fee.Variations.Where(nv => nv.Origin != PriceVariationOrigins.ProductOptions).ToList();
            if (calculationParameters.Options != null && calculationParameters.Options.Count() > 0)
            {
                foreach (var option in calculationParameters.Options)
                {
                    var effectsForFee = option.Effects.Where(b => b.Kind == feeKind)?.ToList();
                    if (effectsForFee != null && effectsForFee.Count() > 0)
                    {
                        foreach (var effect in effectsForFee)
                        {
                            fee.Variations.Add(new FeeVariation
                            {
                                BenefitId            = effect.Code,
                                BenefitSourceId      = option.Code,
                                Origin               = PriceVariationOrigins.ProductOptions,
                                Percentage           = effect.Value,
                                VariationDescription = option.Description,
                                VariationGroup       = effect.Description
                            });
                        }
                    }
                }
            }
            return(fee);
        }
        //Percentage and FixedAmount have a variation that sets them to near lower limit but still above
        public void IterativeCalculatedNearLowerLimit()
        {
            ConfigurationServiceMock       configurationService = new ConfigurationServiceMock();
            PriceCalculationDMNServiceMock priceCalCService     = new PriceCalculationDMNServiceMock(configurationService);
            MarketRatesServiceMock         marketRatesService   = new MarketRatesServiceMock();
            var          priceCalculator = new OfferPriceCalculation(priceCalCService, marketRatesService, configurationService, null);
            FeeCondition regularFee      = new FeeCondition
            {
                //Samo % se testira za sada jer trenutno nema za fixedAmount
                //Samo varijacije uticu na PercentageKind = FeeConditionKinds.OriginationFee,
                Percentage  = (decimal)0.1,
                FixedAmount = new Currency {
                    Amount = 200, Code = "EUR"
                },
                LowerLimit = new Currency {
                    Amount = 20, Code = "EUR"
                },
                UpperLimit = new Currency {
                    Amount = 200, Code = "EUR"
                },
                VariationsDefinitionDMN = "product/price-variations/iterative-fee-in-range-lower.dmn",
                PercentageLowerLimit    = (decimal)0.01,
                PercentageUpperLimit    = 1,
                Title         = "Origination-fee1",
                EffectiveDate = DateTime.Now.AddDays(-1),
                Currencies    = new List <string> {
                    "RSD", "EUR"
                }
            };

            ProductConditions conditions = new ProductConditions
            {
                Fees = new List <FeeCondition> {
                    regularFee
                },
                InterestRates = new List <InterestRateCondition> {
                }
            };
            var arrangementRequest = Utility.GetArangementRequest(conditions);

            Application application = new Application
            {
                ArrangementNumber = "1",
                CustomerName      = "Tester",
                StatusInformation = new StatusInformation
                {
                    Description = "Works as a tester"
                },
                CustomerSegment = "student",
                CollateralModel = "two-co-debtors",

                RiskScore   = 55,
                ChannelCode = "web",
                RequestDate = DateTime.Now
            };

            var result = priceCalculator.CalculatePrice(application, arrangementRequest);

            //Basic assertions
            Assert.Equal("RanToCompletion", result.Status.ToString());

            Assert.Single(result.Result.Conditions.Fees);
            var resultFees = result.Result.Conditions.Fees[0];

            Assert.Single(resultFees.Variations);
            var variation = resultFees.Variations[0];


            //Asserting input
            Assert.Equal(200, resultFees.FixedAmount.Amount);
            Assert.Equal((decimal)0.1, resultFees.Percentage);

            //Asserting output
            Assert.Equal("product/price-variations/iterative-fee-in-range-lower.dmn", resultFees.VariationsDefinitionDMN);
            Assert.Equal((decimal)0.03, resultFees.CalculatedPercentage);
            Assert.Equal((decimal) - 0.07, variation.Percentage);
            Assert.Equal(22, resultFees.CalculatedFixedAmount);
            Assert.Equal(-178, variation.FixedAmount);
        }
        //Percentage and FixedAmount have two variations that sets them over upper limit and calculated should be equal to upper limit
        public void IterativeCalculatedOverUpperLimitMultipleVariations()
        {
            ConfigurationServiceMock       configurationService = new ConfigurationServiceMock();
            PriceCalculationDMNServiceMock priceCalCService     = new PriceCalculationDMNServiceMock(configurationService);
            MarketRatesServiceMock         marketRatesService   = new MarketRatesServiceMock();
            var          priceCalculator = new OfferPriceCalculation(priceCalCService, marketRatesService, configurationService, null);
            FeeCondition regularFee      = new FeeCondition
            {
                Percentage  = (decimal)0.1,
                FixedAmount = new Currency {
                    Amount = 20, Code = "EUR"
                },
                LowerLimit = new Currency {
                    Amount = 20, Code = "EUR"
                },
                UpperLimit = new Currency {
                    Amount = 200, Code = "EUR"
                },
                VariationsDefinitionDMN = "product/price-variations/iterative-multiple-fee-var-over-range.dmn",
                PercentageLowerLimit    = (decimal)0.05,
                PercentageUpperLimit    = 1,
                Title         = "Origination-fee1",
                EffectiveDate = DateTime.Now.AddDays(-1),
                Currencies    = new List <string> {
                    "RSD", "EUR"
                }
            };

            ProductConditions conditions = new ProductConditions
            {
                Fees = new List <FeeCondition> {
                    regularFee
                },
                InterestRates = new List <InterestRateCondition> {
                }
            };
            var arrangementRequest = Utility.GetArangementRequest(conditions);

            Application application = new Application
            {
                ArrangementNumber = "1",
                CustomerName      = "Tester",
                StatusInformation = new StatusInformation
                {
                    Description = "Works as a tester"
                },
                CustomerSegment = "student",
                CollateralModel = "two-co-debtors",

                RiskScore   = 55,
                ChannelCode = "web",
                RequestDate = DateTime.Now
            };

            var result     = priceCalculator.CalculatePrice(application, arrangementRequest);
            var resultFees = result.Result.Conditions.Fees[0];

            var variation = result.Result.Conditions.Fees[0].Variations;

            Assert.Equal("2", variation.Count.ToString());

            var variationOne = variation[0];
            var variationTwo = variation[1];

            Assert.Equal("RanToCompletion", result.Status.ToString());
            Assert.Equal(1, resultFees.CalculatedPercentage);
            Assert.Equal((decimal)0.5, variationOne.Percentage);
            Assert.Equal((decimal)0.6, variationTwo.Percentage);
            Assert.Equal("product/price-variations/iterative-multiple-fee-var-over-range.dmn", resultFees.VariationsDefinitionDMN);
        }
Exemple #11
0
        public void IterativeMultipleOriginationFeesBothCalculated()
        {
            var          OfferPriceCalculation = new OfferPriceCalculation(priceCalCService, marketRatesService, configurationService, null);
            FeeCondition regularFee            = new FeeCondition
            {
                Kind               = FeeConditionKinds.OriginationFee,
                ServiceCode        = "",
                ServiceDescription = "",
                Percentage         = (decimal)0.2,
                FixedAmount        = new Currency {
                    Amount = 200, Code = "RSD"
                },
                LowerLimit = new Currency {
                    Amount = 200, Code = "RSD"
                },
                UpperLimit = new Currency {
                    Amount = 4000, Code = "RSD"
                },
                PercentageLowerLimit = (decimal)0.01,
                PercentageUpperLimit = 1,
                Title         = "Origination-fee1",
                EffectiveDate = DateTime.Now.AddDays(-1),
                Currencies    = new List <string> {
                    "RSD", "EUR"
                }
            };

            FeeCondition regularFee2 = new FeeCondition
            {
                Kind               = FeeConditionKinds.OriginationFee,
                ServiceCode        = "",
                ServiceDescription = "",
                Percentage         = (decimal)0.3,
                FixedAmount        = new Currency {
                    Amount = 300, Code = "RSD"
                },
                LowerLimit = new Currency {
                    Amount = 200, Code = "RSD"
                },
                UpperLimit = new Currency {
                    Amount = 4000, Code = "RSD"
                },
                PercentageLowerLimit = (decimal)0.01,
                PercentageUpperLimit = 1,
                Title         = "Origination-fee2",
                EffectiveDate = DateTime.Now.AddDays(-1),
                Currencies    = new List <string> {
                    "RSD", "EUR"
                }
            };

            ProductConditions conditions = new ProductConditions
            {
                Fees = new List <FeeCondition> {
                    regularFee
                },
                InterestRates = new List <InterestRateCondition> {
                }
            };
            var arrangementRequest = Utility.GetArangementRequest(conditions);

            Application application = new Application
            {
                ArrangementNumber = "1",
                CustomerName      = "Tester",
                StatusInformation = new StatusInformation
                {
                    Description = "Works as a tester"
                },
                CustomerSegment = "student",
                CollateralModel = "two-co-debtors",

                RiskScore   = 55,
                ChannelCode = "web",
                RequestDate = DateTime.Now
            };

            var result = OfferPriceCalculation.CalculatePrice(application, arrangementRequest);

            Assert.Equal("RanToCompletion", result.Status.ToString());
            var resultFees = result.Result.Conditions.Fees;

            //Assert.Equal("2", resultFees.Count.ToString());
            Assert.Equal("1", resultFees.Count.ToString());
            var resultFeeOne = resultFees[0];

            Assert.Empty(resultFeeOne.Variations);
            Assert.Equal((decimal)0.2, resultFeeOne.CalculatedPercentage);
            Assert.Equal(200, resultFeeOne.CalculatedFixedAmount);
            Assert.Null(resultFeeOne.VariationsDefinitionDMN);

            //var resultFeeTwo = resultFees[1];
            //Assert.Empty(resultFeeTwo.Variations);
            //Assert.Equal((decimal)0.3, resultFeeTwo.CalculatedPercentage);
            //Assert.Equal(300, resultFeeTwo.CalculatedFixedAmount);
            //Assert.Null(resultFeeTwo.VariationsDefinitionDMN);
        }
Exemple #12
0
        //Arrangement Request is set to EUR
        //There are no defined variations - Application data does not matter
        //There are two fees, both accounted because they're in the same currency
        public void IterativeTwoInterestRatesDiferentKind()
        {
            var          OfferPriceCalculation = new OfferPriceCalculation(priceCalCService, marketRatesService, configurationService, null);
            FeeCondition regularFee            = new FeeCondition
            {
                //Samo % se testira za sada jer trenutno nema za fixedAmount
                //Samo varijacije uticu na Percentage
                Kind        = FeeConditionKinds.OriginationFee,
                Percentage  = (decimal)0.2,
                FixedAmount = new Currency {
                    Amount = 200, Code = "EUR"
                },
                LowerLimit = new Currency {
                    Amount = 200, Code = "EUR"
                },
                UpperLimit = new Currency {
                    Amount = 4000, Code = "EUR"
                },
                PercentageLowerLimit = (decimal)0.01,
                PercentageUpperLimit = 1,
                Title         = "Origination-fee1",
                EffectiveDate = DateTime.Now.AddDays(-1),
                Currencies    = new List <string> {
                    "RSD", "EUR"
                }
            };

            InterestRateCondition regularInterestEuribor = new InterestRateCondition
            {
                Kind = InterestRateKinds.RegularInterest,
                Rate = new InterestRate
                {
                    BaseRateId      = "EURIBOR-3M",
                    SpreadRateValue = 10
                },
                Title      = "regular-interest",
                Currencies = new List <string> {
                    "EUR"
                }
            };

            InterestRateCondition earlyWithdrawalInterest = new InterestRateCondition
            {
                Kind = InterestRateKinds.EarlyWithdrawalInterest,
                Rate = new InterestRate
                {
                    BaseRateId      = "EARLY-EUR",
                    SpreadRateValue = 2
                },
                Title      = "early-withdrawal-interest",
                Currencies = new List <string> {
                    "EUR"
                }
            };

            ProductConditions conditions = new ProductConditions
            {
                Fees = new List <FeeCondition> {
                    regularFee
                },
                InterestRates = new List <InterestRateCondition> {
                    regularInterestEuribor, earlyWithdrawalInterest
                }
            };
            var arrangementRequest = Utility.GetArangementRequest(conditions);

            Application application = new Application
            {
                ArrangementNumber = "1",
                CustomerName      = "Tester",
                StatusInformation = new StatusInformation
                {
                    Description = "Works as a tester"
                },
                CustomerSegment = "student",
                CollateralModel = "two-co-debtors",

                RiskScore   = 55,
                ChannelCode = "web",
                RequestDate = DateTime.Now
            };

            var result = OfferPriceCalculation.CalculatePrice(application, arrangementRequest);

            Assert.Single(result.Result.Conditions.Fees);
            Assert.Equal("RanToCompletion", result.Status.ToString());

            var resultInterest = result.Result.Conditions.InterestRates[0];
            var resultEarlyWithdrawalInterest = result.Result.Conditions.InterestRates[1];

            Assert.Equal("EURIBOR-3M", resultInterest.Rate.BaseRateId);
            Assert.Equal((decimal)8.5, resultInterest.CalculatedRate);
            Assert.Equal((decimal) - 1.5, resultInterest.Rate.BaseRateValue);
            Assert.Equal((decimal)10.0, resultInterest.Rate.SpreadRateValue);
            //C# won't let this be asserted in any other way
            Assert.Equal("0", resultInterest.Variations.Count.ToString());

            Assert.Equal("EARLY-EUR", resultEarlyWithdrawalInterest.Rate.BaseRateId);
            Assert.Equal((decimal)3.5, resultEarlyWithdrawalInterest.CalculatedRate);
            Assert.Equal((decimal)1.5, resultEarlyWithdrawalInterest.Rate.BaseRateValue);
            Assert.Equal((decimal)2.0, resultEarlyWithdrawalInterest.Rate.SpreadRateValue);

            Assert.Equal(0, resultInterest.CalculatedLowerLimit);
            Assert.Equal(100, resultInterest.CalculatedUpperLimit);
        }