public void RateInInterestRateNull() { ConfigurationServiceMock configurationService = new ConfigurationServiceMock(); PriceCalculationDMNServiceMock priceCalCService = new PriceCalculationDMNServiceMock(configurationService); MarketRatesServiceMock marketRatesService = new MarketRatesServiceMock(); var OfferPriceCalculation = new OfferPriceCalculation(priceCalCService, marketRatesService, configurationService, null); InterestRateCondition intRate = new InterestRateCondition { Kind = InterestRateKinds.RegularInterest, Rate = null, Title = "regular-interest", Currencies = new List <string> { "RSD" } }; ProductConditions conditions = new ProductConditions { InterestRates = new List <InterestRateCondition> { intRate } }; 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()); Assert.Single(result.Result.Conditions.InterestRates); }
public static TermLoanRequest GetArangementRequest(ProductConditions conditions) { var currency = "RSD"; if (conditions.InterestRates != null && conditions.InterestRates.Count > 0) { currency = conditions.InterestRates[0].Currencies[0]; } if (conditions.Fees != null && conditions.Fees.Count > 0) { currency = conditions.Fees[0].Currencies[0]; } return(new TermLoanRequest() { Amount = 50000, Napr = 10, Term = "P30M", Annuity = 325, Currency = currency, DownpaymentAmount = 10000, CalculationDate = DateTime.Today, ProductSnapshot = new ProductSnapshot { Conditions = conditions } }); }
public void InterestRateListNullInConditions() { ConfigurationServiceMock configurationService = new ConfigurationServiceMock(); PriceCalculationDMNServiceMock priceCalCService = new PriceCalculationDMNServiceMock(configurationService); MarketRatesServiceMock marketRatesService = new MarketRatesServiceMock(); var OfferPriceCalculation = new OfferPriceCalculation(priceCalCService, marketRatesService, configurationService, null); ProductConditions conditions = new ProductConditions { Fees = new List <FeeCondition> { }, InterestRates = new List <InterestRateCondition> { null } }; 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()); Assert.Empty(result.Result.Conditions.Fees); }
public ActionResult Index(ProductConditions condition) { return(RedirectToAction("Index", "Template1")); // Check Cost // Product type condition.ListProductType = productService.ListProductType(); // List Limited List <SelectListItem> listLimit = new List <SelectListItem>(); listLimit.Add(new SelectListItem() { Text = "20", Value = "20" }); listLimit.Add(new SelectListItem() { Text = "30", Value = "30", Selected = true }); listLimit.Add(new SelectListItem() { Text = "40", Value = "40" }); listLimit.Add(new SelectListItem() { Text = "50", Value = "50" }); condition.ListLimit = listLimit; return(View(condition)); }
/// <summary> /// Hiển thị danh sách sản phẩm dưới dạng Grid /// </summary> /// <returns></returns> public ActionResult BoxProductGrid(ProductConditions condition) { // Get List City condition.ListCity = placeService.List(0); // Get List District if (condition.CityId > 0) { condition.ListDistrict = placeService.List(condition.CityId); } else { condition.DistrictId = 0; //condition.ListDistrict = placeService.List(1); } // Get List Ward if (condition.DistrictId > 0) { condition.ListWard = placeService.List(condition.DistrictId); } else { condition.WardId = 0; //condition.ListWard = placeService.List(condition.ListDistrict[0].Id); } condition.ListCity.Insert(0, new Entities.Place() { Text = "Chọn tỉnh/thành phố", Id = 0 }); condition.ListDistrict.Insert(0, new Entities.Place() { Text = "Chọn quận/huyện", Id = 0 }); condition.ListWard.Insert(0, new Entities.Place() { Text = "Chọn xã/phường", Id = 0 }); Entities.ProductCondtions e = new Entities.ProductCondtions(); condition.MapFrom(condition, ref e); var lstTemp = productService.List(e); int totalRecord = 0; if (lstTemp.Count > 0) { totalRecord = lstTemp[0].Total.Value; Paging(condition.Page, totalRecord, condition.Limit); } ViewBag.ListProduct = lstTemp; return(PartialView("BoxProductGrid", condition)); }
public void IterativeBaseRateInInterestRateNull() { var OfferPriceCalculation = new OfferPriceCalculation(priceCalCService, marketRatesService, configurationService, null); 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 = null, SpreadRateValue = 10 }, EffectiveDate = DateTime.Now.AddDays(-1), Title = "regular-interest", Currencies = new List <string> { "RSD" } }; ProductConditions conditions = new ProductConditions { InterestRates = new List <InterestRateCondition> { regularInterestEuribor } }; var arrangementRequest = Utility.GetArangementRequest(conditions); Application application = new Application { //U DMN-u pogledati podatke kje uticu na skor iz configa //Ovo ce promeniti broj Percentage za fee i za interest-rate 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()); Assert.Single(result.Result.Conditions.InterestRates); var interestRate = result.Result.Conditions.InterestRates[0]; Assert.Null(interestRate.Rate.BaseRateId); Assert.Equal(0, interestRate.Rate.BaseRateValue); Assert.Equal((decimal)10.0, interestRate.Rate.SpreadRateValue); }
//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); }
public InitiateCalculateOfferCommand(ArrangementKind arrangementKind, string currency, decimal amount, decimal annuity, string term, decimal interestRate, decimal downpaymentAmount, decimal invoiceAmount, decimal minimalDownpaymentPercentage, string channel, decimal?riskScore, string creditRating, decimal?customerValue, decimal?debtToIncome, string customerSegment, string partOfBundle, string collateralModel, ProductConditions productConditions, Conditions conditions, LeadModel campaign, List <ProductOption> productOptions, Dictionary <string, JToken> bundledComponents, decimal downpaymentPercentage, List <ScheduledPeriod> scheduledPeriods, DateTime?calculationDate, DateTime?requestDate, DateTime?approvalDate, DateTime?signingDate, DateTime?disbursmentDate, DateTime?firstInstallmentDate, DateTime?maturityDate, string gracePeriod, DateTime?gracePeriodStartDate, string drawdownPeriod, DateTime?drawdownPeriodStartDate, RepaymentType?repaymentType, int numberOfInstallments, int minimumDaysForFirstInstallment, bool adjustFirstInstallment, bool payFeeFromDisbursement, SimpleSchedule installmentSchedule, IntercalarInterestRepaymentType intercalarInterestRepaymentType) { ArrangementKind = arrangementKind; Currency = currency; Amount = amount; Annuity = annuity; Term = term; InterestRate = interestRate; DownpaymentAmount = downpaymentAmount; InvoiceAmount = invoiceAmount; MinimalDownpaymentPercentage = minimalDownpaymentPercentage; Channel = channel; RiskScore = riskScore; CreditRating = creditRating; CustomerValue = customerValue; DebtToIncome = debtToIncome; CustomerSegment = customerSegment; PartOfBundle = partOfBundle; CollateralModel = collateralModel; ProductConditions = productConditions; Conditions = conditions; Campaign = campaign; ProductOptions = productOptions; BundledComponents = bundledComponents; DownpaymentPercentage = downpaymentPercentage; ScheduledPeriods = scheduledPeriods; CalculationDate = calculationDate ?? DateTime.Now; RequestDate = requestDate ?? DateTime.Now; ApprovalDate = approvalDate; SigningDate = signingDate; DisbursmentDate = disbursmentDate; FirstInstallmentDate = firstInstallmentDate; MaturityDate = maturityDate; GracePeriod = gracePeriod; GracePeriodStartDate = gracePeriodStartDate; DrawdownPeriod = drawdownPeriod; DrawdownPeriodStartDate = drawdownPeriodStartDate; RepaymentType = repaymentType ?? Domain.Calculations.InstallmentPlanCalculation.RepaymentType.FixedAnnuity; NumberOfInstallments = numberOfInstallments; MinimumDaysForFirstInstallment = minimumDaysForFirstInstallment; AdjustFirstInstallment = adjustFirstInstallment; PayFeeFromDisbursement = payFeeFromDisbursement; InstallmentSchedule = installmentSchedule; IntercalarInterestRepaymentType = intercalarInterestRepaymentType; }
public ActionResult BoxProduct(ProductConditions condition) { if (condition.displayType == "Grid") { return(BoxProductGrid(condition)); } else { return(BoxProductList(condition)); } }
public void BaseRateInInterestRateNull() { ConfigurationServiceMock configurationService = new ConfigurationServiceMock(); PriceCalculationDMNServiceMock priceCalCService = new PriceCalculationDMNServiceMock(configurationService); MarketRatesServiceMock marketRatesService = new MarketRatesServiceMock(); var OfferPriceCalculation = new OfferPriceCalculation(priceCalCService, marketRatesService, configurationService, null); 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 = null, SpreadRateValue = 10 }, EffectiveDate = DateTime.Now.AddDays(-1), Title = "regular-interest", Currencies = new List <string> { "RSD" } }; ProductConditions conditions = new ProductConditions { InterestRates = new List <InterestRateCondition> { regularInterestEuribor } }; 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()); Assert.Single(result.Result.Conditions.InterestRates); var interestRate = result.Result.Conditions.InterestRates[0]; Assert.Null(interestRate.Rate.BaseRateId); Assert.Equal(0, interestRate.Rate.BaseRateValue); Assert.Equal((decimal)10.0, interestRate.Rate.SpreadRateValue); }
public void IterativeRateInInterestRateNull() { var OfferPriceCalculation = new OfferPriceCalculation(priceCalCService, marketRatesService, configurationService, null); InterestRateCondition intRate = new InterestRateCondition { Kind = InterestRateKinds.RegularInterest, Rate = null, Title = "regular-interest", Currencies = new List <string> { "RSD" } }; ProductConditions conditions = new ProductConditions { InterestRates = new List <InterestRateCondition> { intRate } }; var arrangementRequest = Utility.GetArangementRequest(conditions); Application application = new Application { //U DMN-u pogledati podatke kje uticu na skor iz configa //Ovo ce promeniti broj Percentage za fee i za interest-rate 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()); Assert.Single(result.Result.Conditions.InterestRates); }
public static Application GetApplication(ProductConditions conditions) { return(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, ArrangementRequests = new List <ArrangementRequest> { GetArangementRequest(conditions) } }); }
public async Task <PriceCalculationResponse> Handle(InitiatePriceCalculationCommand message, CancellationToken cancellationToken) { ProductConditions conditions = await _priceCalculation.ReadVariationDefinitions(new ProductConditions { Fees = message.Fees == null ? null : new List <FeeCondition>(message.Fees), InterestRates = message.InterestRates == null ? null : new List <InterestRateCondition>(message.InterestRates) }); var calcParams = new PriceCalculationParameters { InterestRates = conditions.InterestRates, Fees = conditions.Fees, Amount = message.Amount, Term = message.Term, Currency = message.Currency, Channel = message.Channel, RiskScore = message.RiskScore, CustomerSegment = message.CustomerSegment, CollateralModel = message.CollateralModel, PartOfBundle = message.ProductBundling, Campaign = message.Campaign, Options = message.ProductOptions, CreditRating = message.CreditRating, CustomerValue = message.CustomerValue, DebtToIncome = message.DebtToIncome, AdditionalProperties = message.BundledComponents }; var calcResult = await _priceCalculator.CalculatePrice(calcParams); var result = new PriceCalculationResponse { Fees = calcResult.Fees, InterestRates = calcResult.InterestRates, Napr = calcResult.Napr }; return(result); }
public async Task <ProductConditions> ReadVariationDefinitions(ProductConditions conditions) { if (conditions == null) { return(null); } if (conditions.InterestRates != null) { foreach (InterestRateCondition rate in conditions.InterestRates) { if (rate.VariationsDefinition != null) { rate.VariationsDefinitionDMN = await configurationService.GetEffective(rate.VariationsDefinition); } if (rate.UpperLimitVariationsDefinition != null) { rate.UpperLimitVariationsDefinitionDMN = await configurationService.GetEffective(rate.UpperLimitVariationsDefinition); } if (rate.LowerLimitVariationsDefinition != null) { rate.LowerLimitVariationsDefinitionDMN = await configurationService.GetEffective(rate.LowerLimitVariationsDefinition); } } } if (conditions.Fees != null) { foreach (FeeCondition fee in conditions.Fees) { if (fee.VariationsDefinition != null) { fee.VariationsDefinitionDMN = await configurationService.GetEffective(fee.VariationsDefinition); } } } return(conditions.Copy()); }
//No variations, calc rates should be as they are set in the request //Rate is within limits public void NoVariationsBelowLimitWithoutMarketRate() { ConfigurationServiceMock configurationService = new ConfigurationServiceMock(); PriceCalculationDMNServiceMock priceCalCService = new PriceCalculationDMNServiceMock(configurationService); MarketRatesServiceMock marketRatesService = new MarketRatesServiceMock(); var OfferPriceCalculation = new OfferPriceCalculation(priceCalCService, marketRatesService, configurationService, null); InterestRateCondition regularInterestEuribor = new InterestRateCondition { //This base rate id removes -1.5 from spreadRateValue, making rate under limit Kind = InterestRateKinds.RegularInterest, Rate = new InterestRate { BaseRateId = "EURIBOR-6M", SpreadRateValue = (decimal)9.9 }, UpperLimit = new InterestRate { BaseRateId = "EURIBOR-6M", SpreadRateValue = 18 }, LowerLimit = new InterestRate { BaseRateId = "EURIBOR-6M", SpreadRateValue = 10 }, Title = "regular-interest", Currencies = new List <string> { "EUR" } }; ProductConditions conditions = new ProductConditions { Fees = new List <FeeCondition> { }, InterestRates = new List <InterestRateCondition> { regularInterestEuribor } }; Application application = Utility.GetApplication(conditions); var arrangementRequest = application.ArrangementRequests[0] as TermLoanRequest; var priceCalculationConditions = Utility.GetPriceCalculationParameterFromTermLoanRequest(arrangementRequest); var variationsDefinition = Utility.GetVariationDefinitionParamsFromApplication(application); var result = OfferPriceCalculation.CalculatePrice(application, arrangementRequest); var resultInterest = result.Result.Conditions.InterestRates[0]; //Basic assertions Assert.Equal("RanToCompletion", result.Status.ToString()); Assert.Equal("0", resultInterest.Variations.Count.ToString()); //Asserting input parameters Assert.Equal("EURIBOR-6M", resultInterest.Rate.BaseRateId); Assert.Equal(0, resultInterest.Rate.BaseRateValue); Assert.Equal((decimal)9.9, resultInterest.Rate.SpreadRateValue); Assert.Equal("EURIBOR-6M", resultInterest.UpperLimit.BaseRateId); Assert.Equal(0, resultInterest.UpperLimit.BaseRateValue); Assert.Equal((decimal)18.0, resultInterest.UpperLimit.SpreadRateValue); Assert.Equal("EURIBOR-6M", resultInterest.LowerLimit.BaseRateId); Assert.Equal(0, resultInterest.LowerLimit.BaseRateValue); Assert.Equal((decimal)10.0, resultInterest.LowerLimit.SpreadRateValue); //Asserting Napr and calculation results Assert.Equal((decimal)10.0, ((TermLoanRequest)result.Result).Napr); Assert.Equal((decimal)10.0, resultInterest.CalculatedRate); Assert.Equal((decimal)10.0, resultInterest.CalculatedLowerLimit); Assert.Equal((decimal)18.0, resultInterest.CalculatedUpperLimit); }
//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); }
//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); }
public async Task <ArrangementRequest> Handle(InitiateCalculateOfferCommand message, CancellationToken cancellationToken) { ProductConditions conditions = await _priceCalculation.ReadVariationDefinitions(message.ProductConditions); var parameters = Mapper.Map <InitiateCalculateOfferCommand, ArrangementRequestInitializationParameters>(message); try { parameters.MaturityDate = Utility.GetEndDateFromPeriod(parameters.Term, message.CalculationDate); } catch (InvalidTermException) { // do nothing } ArrangementRequest result = _requestFactory.GetForArrangementKind(parameters, message.ArrangementKind); if (parameters.MaturityDate.HasValue && result.IsFinanceService()) { FinanceServiceArrangementRequest fsr = result as FinanceServiceArrangementRequest; fsr.MaturityDate = parameters.MaturityDate.Value; } result.ParentProductCode = message.PartOfBundle; result.Campaign = message.Campaign; result.Options = message.ProductOptions; if (result is FinanceServiceArrangementRequest finRequest) { finRequest.CollateralModel = message.CollateralModel; } Dictionary <string, OptionGroup> productShapsotOptions = new Dictionary <string, OptionGroup>(); if (message.ProductOptions != null) { foreach (var option in message.ProductOptions) { if (productShapsotOptions.TryGetValue(option.GroupCode, out OptionGroup optionGroup)) { optionGroup.Options.Add(new Option { Code = option.Code, Description = option.Description, Effects = option.Effects }); } else { productShapsotOptions.Add(option.GroupCode, new OptionGroup { Code = option.GroupCode, Description = option.GroupDescription, Options = new List <Option> { new Option { Code = option.Code, Description = option.Description, Effects = option.Effects } } }); } } } result.ProductSnapshot = new ProductSnapshot { Conditions = conditions, Campaign = message.Campaign, OptionGroups = productShapsotOptions.Values.ToList(), MinimumDaysForFirstInstallment = message.MinimumDaysForFirstInstallment }; OfferApplication application = new OfferApplication { CustomerSegment = message.CustomerSegment, CollateralModel = message.CollateralModel, RiskScore = message.RiskScore ?? null, ChannelCode = message.Channel, DebtToIncome = message.DebtToIncome, CustomerValue = message.CustomerValue, CreditRating = message.CreditRating, RequestDate = message.RequestDate }; try { _logger.LogInformation("Calculating offer for term: {term}, annuity: {annutiy} and amount {amount} and interest rate: {rate}", message.Term, message.Annuity, message.Amount, message.InterestRate); result = _calculatorProvider.Calculate(result, application, message.BundledComponents); RemoveDmnFields(result); try { await _auditClient.WriteLogEntry(AuditLogEntryAction.Execute, AuditLogEntryStatus.Success, "application", application.ApplicationNumber, "Calculating offer for term: " + message.Term + ", annuity: " + message.Annuity + " and amount " + message.Amount, new { }); } catch (Exception ex) { _logger.LogError(ex, "Audit error in UpdateApplicationStatusCommandHandler"); } return(result); } catch (MaxNumberOfIterationsException e) { _logger.LogInformation("Error in calculation: {calcErr}. Command data: {command}", e.Message, message); throw e; } catch (Exception exp) { _logger.LogError(exp, "Exception while calculating offer for data, term: {term}, annuity: {annutiy} and amount {amount} and interest rate: {rate}", message.Term, message.Annuity, message.Amount, message.InterestRate); throw new NotImplementedException(exp.Message); } }
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); }
public Task <ProductConditions> ReadVariationDefinitions(ProductConditions condition) { throw new NotImplementedException(); }
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); }
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); }
//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); }
public static PriceCalculationParameters GetPriceCalculationParametersFromConditions(ProductConditions conditions) { return(GetPriceCalculationParameterFromTermLoanRequest(GetArangementRequest(conditions))); }
//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); }
//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); }
//No variations, calc rates should be as they are set in the request //Rate is within limits public void IterativeNoVariationsRateAboveLimitBasedOnMarketRate() { var OfferPriceCalculation = new OfferPriceCalculation(priceCalCService, marketRatesService, configurationService, null); InterestRateCondition regularInterestEuribor = new InterestRateCondition { //This base rate id removes -1.5 from spreadRateValue, making rate under limit Kind = InterestRateKinds.RegularInterest, Rate = new InterestRate { BaseRateId = "EURIBOR-4M", SpreadRateValue = 17 }, UpperLimit = new InterestRate { BaseRateId = "EURIBOR-6M", SpreadRateValue = 18 }, LowerLimit = new InterestRate { BaseRateId = "EURIBOR-6M", SpreadRateValue = 10 }, Title = "regular-interest", Currencies = new List <string> { "EUR" } }; ProductConditions conditions = new ProductConditions { Fees = new List <FeeCondition> { }, InterestRates = new List <InterestRateCondition> { regularInterestEuribor } }; 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); var resultInterest = result.Result.Conditions.InterestRates[0]; //Basic assertions Assert.Equal("RanToCompletion", result.Status.ToString()); Assert.Equal("0", resultInterest.Variations.Count.ToString()); //Asserting input parameters Assert.Equal("EURIBOR-4M", resultInterest.Rate.BaseRateId); Assert.Equal(2, resultInterest.Rate.BaseRateValue); Assert.Equal(17, resultInterest.Rate.SpreadRateValue); Assert.Equal("EURIBOR-6M", resultInterest.UpperLimit.BaseRateId); Assert.Equal(0, resultInterest.UpperLimit.BaseRateValue); Assert.Equal((decimal)18.0, resultInterest.UpperLimit.SpreadRateValue); Assert.Equal("EURIBOR-6M", resultInterest.LowerLimit.BaseRateId); Assert.Equal(0, resultInterest.LowerLimit.BaseRateValue); Assert.Equal((decimal)10.0, resultInterest.LowerLimit.SpreadRateValue); //Asserting Napr and calculation results Assert.Equal((decimal)18.0, ((TermLoanRequest)result.Result).Napr); Assert.Equal((decimal)18.0, resultInterest.CalculatedRate); Assert.Equal((decimal)10.0, resultInterest.CalculatedLowerLimit); Assert.Equal((decimal)18.0, resultInterest.CalculatedUpperLimit); }