Exemple #1
0
        public async Task <ArrangementRequest> UpdateArrangementRequest(ArrangementRequest arrangementRequest)
        {
            if (arrangementRequest != null)
            {
                if (long.TryParse(arrangementRequest.ApplicationNumber, out long appNumberLong))
                {
                    var request = GetArrangementRequest(appNumberLong, arrangementRequest.ArrangementRequestId, null, null);
                    if (request == null)
                    {
                        return(null);
                    }
                    if (arrangementRequest is FinanceServiceArrangementRequest finArrRequest)
                    {
                        var app = _context.Applications.First(a => a.ApplicationNumber.Equals(arrangementRequest.ApplicationNumber));
                        if (app.ProductCode.Equals(arrangementRequest.ProductCode))
                        {
                            app.LoanToValue         = finArrRequest.LoanToValue;
                            app.MaximalAmount       = finArrRequest.MaximalAmount;
                            app.MaximalAnnuity      = finArrRequest.MaximalAnnuity;
                            app.AmountLimitBreached = finArrRequest.Amount > arrangementRequest.ProductSnapshot.MaximalAmount.Amount ? true : false;
                        }
                    }
                    arrangementRequest.ProductSnapshotDb = await _productSnapshotRepository.PostProductSnapshot(arrangementRequest.ProductSnapshot);

                    _context.Entry(request).CurrentValues.SetValues(arrangementRequest);
                    _context.SaveChanges();
                    return(arrangementRequest);
                }
            }
            return(null);
        }
Exemple #2
0
        public ArrangementRequest GetArrangementRequest(long applicationNumber, int arrangementRequestId, string include, string trim)
        {
            string[] inclusions = string.IsNullOrEmpty(include) ? new string[] { } : include.Split(',');

            var application = _applicationRepository.GetAsync(applicationNumber).Result;

            if (application == null)
            {
                return(null);
            }

            var queryable = _context.ArrangementRequests.Include(x => x.ProductSnapshotDb)
                            .Where(d => d.ApplicationId == applicationNumber &&
                                   d.ArrangementRequestId == arrangementRequestId).AsQueryable();

            if (inclusions.Contains("collateral-requirements"))
            {
                queryable = queryable.Include(x => (x as FinanceServiceArrangementRequest).CollateralRequirements);
            }

            ArrangementRequest request = queryable.FirstOrDefault();

            if (request == null)
            {
                return(null);
            }
            if (request is TermLoanRequest termLoan)
            {
                LoadDisbursementInfoAmount(termLoan);
            }
            return(request);
        }
Exemple #3
0
        public async Task <ArrangementRequest> CalculateAsCalculationService(
            ArrangementRequest arrangementRequest, PriceCalculationParameters priceCalculationParameters)
        {
            List <PricedScheduledPeriod> pricedAndScheduledPeriods = null;

            if (priceCalculationParameters.ScheduledPeriods != null)
            {
                // var conversionMethod = await _configurationService.GetEffective("offer/fee-currency-conversion-method", "Buy to middle");
                pricedAndScheduledPeriods = SchedulingPeriodsResolver.PricePeriods(arrangementRequest,
                                                                                   priceCalculationParameters, _offerPriceCalculation);
            }

            // Perform price calculation for main conditions (whole repayment period)
            List <ScheduledPeriod> scheduledPeriods = new List <ScheduledPeriod>();
            var hasPeriods = priceCalculationParameters.ScheduledPeriods != null && priceCalculationParameters.ScheduledPeriods.Count() > 0;

            if (hasPeriods)
            {
                priceCalculationParameters.ScheduledPeriods.ForEach(p => scheduledPeriods.Add(p));
                priceCalculationParameters.ScheduledPeriods.Clear();
            }
            _ = await _offerPriceCalculation.CalculatePrice(arrangementRequest, priceCalculationParameters);

            if (hasPeriods)
            {
                priceCalculationParameters.ScheduledPeriods = scheduledPeriods;
            }

            var request = new CalculateInstallmentPlanRequestCS
            {
                Amount = (double)(arrangementRequest is FinanceServiceArrangementRequest fR ? fR.Amount : 0),
                RegularInterestPercentage = (double)(arrangementRequest?.Conditions?.InterestRates?.Where(r => r.Kind == InterestRateKinds.RegularInterest && string.IsNullOrEmpty(r.Periods)).Select(r => r.CalculatedRate).FirstOrDefault() ?? 0),
                // todo check
                StartDate = priceCalculationParameters.RequestDate,
                Currency  = arrangementRequest is FinanceServiceArrangementRequest fRc?GetCurrencyCode(fRc.Currency) : "978",
                                RegularInterestUnitOfTime = CalculationService.Services.SimpleUnitOfTime.Y,
                                Term    = arrangementRequest is FinanceServiceArrangementRequest fRt ? fRt.Term : "0",
                                Periods = pricedAndScheduledPeriods
            };

            request = AppendFees(request, arrangementRequest);
            request = AppendPredefinedPeriods(request, arrangementRequest);

            var plan = _calculator.CalculateInstallmentPlan(request);

            arrangementRequest.CalculationDate      = priceCalculationParameters.RequestDate;
            arrangementRequest.NumberOfInstallments = (int)(plan.NumberOfInstallments ?? 0);
            arrangementRequest.InstallmentPlan      = AggregatesModel.ApplicationAggregate.InstallmentPlanRow.FromInstallmentPlanCSList(plan.Installments);
            // TODO Think about this casts
            if (arrangementRequest is FinanceServiceArrangementRequest fSR)
            {
                fSR.Eapr = (decimal)(plan.EffectiveInterestRate ?? 0);
                if (arrangementRequest is TermLoanRequest trl)
                {
                    trl.Annuity = (decimal)(plan.Annuity ?? 0);
                }
            }
            return(arrangementRequest);
        }
        private ArrangementRequest CalculateAsBasic(ArrangementRequest arrangementRequest, PriceCalculationParameters priceCalculationParameters)
        {
            var priceCalc        = (OfferPriceCalculation)_serviceProvider.GetService(typeof(OfferPriceCalculation));
            var conversionMethod = _configurationService.GetEffective("offer/fee-currency-conversion-method", "Buy to middle").Result;

            arrangementRequest.CalculateOffer(priceCalculationParameters, priceCalc, conversionMethod);
            return(arrangementRequest);
        }
 public ActionResult Edit(ArrangementRequest revisionarreglo)
 {
     if (ModelState.IsValid)
     {
         db.Entry(revisionarreglo).State = EntityState.Modified;
         db.SaveChanges();
         return(RedirectToAction("Index"));
     }
     return(View(revisionarreglo));
 }
        public async Task <ArrangementRequest> CalculatePrice(ArrangementRequest request, PriceCalculationParameters calcParams)
        {
            decimal amount = 0;
            string  term   = null;

            if (request is TermLoanRequest termLoanRequest)
            {
                amount = termLoanRequest.Amount;
                term   = termLoanRequest.Term;
            }
            var res = await CalculatePrice(calcParams);

            request.MergePriceCalculationResults(res);
            if (request is TermLoanRequest tlRequest)
            {
                #region TermLoanRequest handling
                calcParams.InterestRates   = res.InterestRates;
                calcParams.Fees            = res.Fees;
                calcParams.OtherConditions = res.OtherConditions;
                var priceCalcualtionChanged = res.ResultChanged;

                tlRequest.ResolveCalculationParameters();

                var iterations = 1; // One iteration already happend (in initial calculation)
                while (priceCalcualtionChanged)
                {
                    if (iterations > maxNumberOfIterations)
                    {
                        throw new MaxNumberOfIterationsException("Maximum number of iterations exceeded.");
                    }
                    res = await CalculatePrice(calcParams);

                    priceCalcualtionChanged = res.ResultChanged;

                    if (term == null)
                    {
                        tlRequest.Term = null;
                    }
                    else if (amount == 0)
                    {
                        tlRequest.Amount = 0;
                    }
                    else
                    {
                        tlRequest.Annuity = 0;
                    }

                    tlRequest.ResolveCalculationParameters();
                    iterations++;
                }
                #endregion
            }
            return(request);
        }
Exemple #7
0
        public async Task <bool?> SetArragementRequestAvailability(long applicationId, int arrangementRequestId, bool enabled)
        {
            ArrangementRequest arrRequest = GetArrangementRequest(applicationId, arrangementRequestId, null, null);

            if (arrRequest == null)
            {
                return(null);
            }
            arrRequest.Enabled = enabled;
            return(true);
        }
        public ActionResult Create(ArrangementRequest revisionarreglo)
        {
            if (ModelState.IsValid)
            {
                db.ArrangementRequests.Add(revisionarreglo);
                db.SaveChanges();
                return(RedirectToAction("Index"));
            }

            return(View(revisionarreglo));
        }
        public async Task <bool> Handle(AddSecuredDealLinkCommand message, CancellationToken cancellationToken)
        {
            var longApplicationNumber               = long.Parse(message.ApplicationNumber);
            CollateralRequirement  requirement      = _arrangementRequestRepository.GetCollateralRequirementById(longApplicationNumber, message.ArrangementRequestId, message.CollateralRequirementId);
            List <SecuredDealLink> securedDealLinks = requirement?.SecuredDealLinks ?? new List <SecuredDealLink>();
            ArrangementRequest     request          = _arrangementRequestRepository.GetArrangementRequest(longApplicationNumber, message.ArrangementRequestId);

            if (request is FinanceServiceArrangementRequest finRequest)
            {
                CurrencyConverter currencyConverter = new CurrencyConverter();
                var currencyConversionMethod        = _configurationService.GetEffective("offer/currency-conversion-method").Result;
                var pledgedValueInLoanCurrency      = currencyConverter.CurrencyConvert(message.PledgedValueInCollateralCurrency, message.ArrangementCurrency, finRequest.Currency, DateTime.Today.ToString("o", CultureInfo.InvariantCulture), currencyConversionMethod);

                var existingSecuredDealLink = securedDealLinks.Where
                                                  (x => x.ArrangementRequestId.Equals(message.ArrangementRequestId) &&
                                                  x.ApplicationNumber.Equals(message.ApplicationNumber) &&
                                                  x.ArrangementNumber.Equals(message.ArrangementNumber)).FirstOrDefault();

                if (existingSecuredDealLink != null)
                {
                    existingSecuredDealLink.PledgedValueInCollateralCurrency = message.PledgedValueInCollateralCurrency;
                    existingSecuredDealLink.PledgedValueInLoanCurrency       = pledgedValueInLoanCurrency;
                    requirement.SecuredDealLinks = securedDealLinks;
                }
                else
                {
                    securedDealLinks.Add(new SecuredDealLink
                    {
                        ApplicationNumber                = message.ApplicationNumber,
                        ArrangementNumber                = message.ArrangementNumber,
                        ArrangementRequestId             = message.ArrangementRequestId,
                        PledgedValueInCollateralCurrency = message.PledgedValueInCollateralCurrency,
                        PledgedValueInLoanCurrency       = pledgedValueInLoanCurrency
                    });
                    requirement.SecuredDealLinks = securedDealLinks;
                }
                _arrangementRequestRepository.UpdateCollateralRequirement(requirement);
                var result = await _arrangementRequestRepository.UnitOfWork.SaveEntitiesAsync();

                var msgBuilder =
                    _messageEventFactory.CreateBuilder("offer", "secured-deal-link-changed")
                    .AddHeaderProperty("application-number", message.ApplicationNumber)
                    .AddHeaderProperty("username", "ALL");

                _bus.Publish(msgBuilder.Build());
                return(result);
            }
            else
            {
                return(false);
            }
        }
        //
        // GET: /Arrangements/CreateFromRequest

        public ActionResult CreateFromRequest(int id)
        {
            ArrangementRequest request = db.ArrangementRequests.Find(id);

            return(View("Create", new Arrangement {
                SchoolId = request.SchoolId,
                School = request.School,
                OrganizationId = request.OrganizationId,
                Organization = request.Organization,
                ReceiptDate = DateTime.Today,
                SignatureDate = DateTime.Today,
                ValidFrom = DateTime.Today,
                ExpiryDate = DateTime.Today
            }));
        }
        public ActionResult DeleteConfirmed(int id)
        {
            try
            {
                ArrangementRequest revisionarreglo = db.ArrangementRequests.Find(id);
                db.ArrangementRequests.Remove(revisionarreglo);
                db.SaveChanges();
            }
            catch (System.Data.Entity.Infrastructure.DbUpdateException)
            {
                return(View("DeleteUnsuccessful"));
            }

            return(RedirectToAction("Index"));
        }
Exemple #12
0
        public List <CollateralRequirementValidation> ValidateCollateralRequirement(long applicationNumber, int arrangementRequestId)
        {
            List <CollateralRequirementValidation> collValidationList = new List <CollateralRequirementValidation>();
            ArrangementRequest arrRequest = GetArrangementRequest(applicationNumber, arrangementRequestId, "collateral-requirements", null);

            if (arrRequest == null || !(arrRequest is FinanceServiceArrangementRequest))
            {
                return(null);
            }
            var collReq = ((FinanceServiceArrangementRequest)arrRequest).CollateralRequirements;

            foreach (var item in collReq)
            {
                CollateralRequirementValidation collValidation = new CollateralRequirementValidation
                {
                    ApplicationNumber         = applicationNumber,
                    ArrangementRequestId      = arrangementRequestId,
                    CollateralArrangementCode = item.CollateralArrangementCode,
                    CollateralRequirementId   = item.CollateralRequirementId
                };
                if (item.SecuredDealLinks == null)
                {
                    collValidation.ValidationResult = CollateralValidationResult.NotFilled;
                }
                else
                {
                    if (item.MinimalCoverage > 0)
                    {
                        if (item.MinimalCoverageInLoanCurrency > item.ActualCoverage)
                        {
                            collValidation.ValidationResult = CollateralValidationResult.BelowMinimalCoverage;
                        }
                        else
                        {
                            collValidation.ValidationResult = CollateralValidationResult.Filled;
                        }
                    }
                    else
                    {
                        collValidation.ValidationResult = CollateralValidationResult.Filled;
                    }
                }
                collValidationList.Add(collValidation);
            }


            return(collValidationList);
        }
Exemple #13
0
        public List <ArrangementRequest> GetBundledRequests(ArrangementRequest arrangementRequest, bool includeSingletons = false)
        {
            var application = _applicationRepository.GetAsync(arrangementRequest.ApplicationId).Result;

            if (application == null)
            {
                return(null);
            }
            var bundledRequests = GetArrangementRequestsQuery(arrangementRequest.ApplicationId, true)
                                  .Where(r =>
                                         r.ArrangementRequestId != arrangementRequest.ArrangementRequestId &&
                                         r.ParentProductCode == arrangementRequest.ProductCode &&
                                         r.ProductSnapshot.IsSingleton == includeSingletons)
                                  .ToList();

            return(bundledRequests);
        }
Exemple #14
0
 private CalculateInstallmentPlanRequestCS AppendPredefinedPeriods(
     CalculateInstallmentPlanRequestCS request, ArrangementRequest arrangementRequest)
 {
     // TODO Chech this hardcoded cast
     if (arrangementRequest is TermLoanRequest termLoanRequest)
     {
         if (termLoanRequest.GracePeriod != null && termLoanRequest.GracePeriodStartDate != null)
         {
             request.GracePeriodEnd = Utility.GetEndDateFromPeriod(termLoanRequest.GracePeriod, termLoanRequest.GracePeriodStartDate);
         }
         if (termLoanRequest.DrawdownPeriod != null && termLoanRequest.DrawdownPeriodStartDate != null)
         {
             request.DrawdownPeriodEnd = Utility.GetEndDateFromPeriod(termLoanRequest.DrawdownPeriod, termLoanRequest.DrawdownPeriodStartDate);
         }
     }
     return(request);
 }
Exemple #15
0
        /*public static List<PricedScheduledPeriod> ScheduleAndPricePeriods(ResolveSchedulingPeriodsRequest request,
         *  ArrangementRequest arrangementRequest, PriceCalculationParameters priceParams, OfferPriceCalculation priceCalc,
         *  string conversionMethod)
         * {
         *  var scheduledAndPricedPeriods = new List<PricedScheduledPeriod>();
         *  ArrangementRequest arrangementRequestTemp;
         *  foreach (var period in priceParams.ScheduledPeriods)
         *  {
         *      arrangementRequestTemp = Mapper.Map<ArrangementRequest, ArrangementRequest>(arrangementRequest);
         *      arrangementRequestTemp.CalculateOffer(priceParams, priceCalc, conversionMethod);
         *      scheduledAndPricedPeriods.Add(new PricedScheduledPeriod
         *      {
         *          Percentage = (double)(arrangementRequestTemp?.Conditions?.InterestRates?.Where(r => r.Kind == InterestRateKinds.RegularInterest).Select(r => r.CalculatedRate).FirstOrDefault() ?? 0),
         *          PeriodType = period.PeriodType,
         *          StartDate = period.StartDate,
         *          EndDate = period.EndDate,
         *          // TODO To be resolved from DMN maybe?
         *          UnitOfTime = CalculationService.Services.SimpleUnitOfTime.Y
         *      });
         *  }
         *  return scheduledAndPricedPeriods;
         * }*/

        public static List <PricedScheduledPeriod> PricePeriods(
            ArrangementRequest arrangementRequest, PriceCalculationParameters priceParams,
            OfferPriceCalculation priceCalc)
        {
            var scheduledAndPricedPeriods = new List <PricedScheduledPeriod>();
            var scheduledPeriods          = new List <ScheduledPeriod>();
            var rates = new List <InterestRateCondition>();

            if (priceParams.ScheduledPeriods != null)
            {
                priceParams.ScheduledPeriods.ForEach(p => scheduledPeriods.Add(p));
            }
            if (priceParams.InterestRates != null)
            {
                priceParams.InterestRates.ForEach(r => rates.Add(r));
            }
            foreach (var period in scheduledPeriods)
            {
                priceParams.ScheduledPeriods.Clear();
                priceParams.ScheduledPeriods.Add(period);
                _ = priceCalc.CalculatePrice(arrangementRequest, priceParams).Result;
                // arrangementRequest.CalculateOffer(priceParams, priceCalc, conversionMethod);
                scheduledAndPricedPeriods.Add(new PricedScheduledPeriod
                {
                    Percentage = (double)(arrangementRequest?.Conditions?.InterestRates?.Where(r => r.Kind == InterestRateKinds.RegularInterest).Select(r => r.CalculatedRate).FirstOrDefault() ?? 0),
                    PeriodType = period.PeriodType,
                    StartDate  = period.StartDate,
                    EndDate    = period.EndDate,
                    // TODO To be resolved from DMN maybe?
                    UnitOfTime = CalculationService.Services.SimpleUnitOfTime.Y
                });
            }
            if (scheduledPeriods != null)
            {
                priceParams.ScheduledPeriods = scheduledPeriods;
            }
            if (rates != null)
            {
                priceParams.InterestRates = rates;
            }
            return(scheduledAndPricedPeriods);
        }
Exemple #16
0
 private void PerformCalculation(OfferApplication application, ArrangementRequest request)
 {
     if (request is FinanceServiceArrangementRequest finR)
     {
         try
         {
             request = _calculatorProvider.Calculate(finR, application);
             //var conversionMethod = _configurationService.GetEffective("offer/fee-currency-conversion-method", "Buy to middle").Result;
             //finR.CalculateOffer(application, _priceCalculator, conversionMethod);
         }
         catch (MaxNumberOfIterationsException e)
         {
             _logger.LogError(e, "Maximanl number of iterations exceeded while calculating price");
             throw e;
         }
         catch (Exception exp)
         {
             _logger.LogError(exp, "An unknown error occured while performing offer calculation");
             throw new InvalidCalculationException();
         }
     }
 }
        public ArrangementRequest Calculate(ArrangementRequest arrangementRequest, Application application = null,
                                            IDictionary <string, JToken> additionalProperties = null)
        {
            var priceCalculationParameters = arrangementRequest.GetPriceCalculationParameters(application);

            if (additionalProperties != null && additionalProperties.Keys.Count() > 0)
            {
                priceCalculationParameters.AdditionalProperties = priceCalculationParameters.AdditionalProperties ?? new Dictionary <string, JToken>();
                priceCalculationParameters.AdditionalProperties = priceCalculationParameters.AdditionalProperties
                                                                  .Concat(additionalProperties
                                                                          .Where(k => !priceCalculationParameters.AdditionalProperties.ContainsKey(k.Key))
                                                                          .ToDictionary(k => k.Key, v => v.Value))
                                                                  .ToDictionary(k => k.Key, v => v.Value);
            }
            var calculationEngine = _configurationService.GetEffective("offer/calculation-engine", "basic").Result;

            switch (calculationEngine)
            {
            case "basic":
                return(CalculateAsBasic(arrangementRequest, priceCalculationParameters));

            case "calculation-service":
                try
                {
                    var calcServiceCalculator = (CalculationServiceCalculator)_serviceProvider.GetService(typeof(CalculationServiceCalculator));
                    return(calcServiceCalculator.CalculateAsCalculationService(arrangementRequest, priceCalculationParameters).Result);
                }
                catch (Exception e)
                {
                    throw e;
                }

            case "simple-calculation":
                return(CalculateBySimpleCalculation(arrangementRequest, priceCalculationParameters));

            default:
                return(CalculateAsBasic(arrangementRequest, priceCalculationParameters));
            }
        }
Exemple #18
0
        public async Task <bool?> Handle(AddAccountNumbersCommand message, CancellationToken cancellationToken)
        {
            ArrangementRequest arrangementRequest = _arrangementRequestRepository.GetArrangementRequest(message.ApplicationNumber, message.ArrangementRequestId);

            if (arrangementRequest == null)
            {
                return(null);
            }
            List <ArrangementAccountInfo> arrangementAccounts;

            if (arrangementRequest.Accounts == null)
            {
                arrangementAccounts = new List <ArrangementAccountInfo>();
            }
            else
            {
                arrangementAccounts = arrangementRequest.Accounts;
            }
            foreach (AccountNumbersData accountData in message.AccountNumbers)
            {
                if (accountData != null)
                {
                    _logger.LogInformation("Adding account number {accountNumbers} for {applicationNumber}", accountData.AccountNumber, message.ApplicationNumber);
                    ArrangementAccountInfo newAccount = new ArrangementAccountInfo
                    {
                        AccountNumber = accountData.AccountNumber,
                        RoleKind      = accountData.RoleKind
                    };
                    arrangementAccounts.Add(newAccount);
                }
            }
            arrangementRequest.Accounts = arrangementAccounts;
            await _arrangementRequestRepository.UpdateArrangementRequest(arrangementRequest);

            return(await _arrangementRequestRepository.UnitOfWork.SaveEntitiesAsync());
        }
Exemple #19
0
        public ArrangementRequest GetForArrangementKind(ArrangementRequestInitializationParameters parameters,
                                                        ArrangementKind?arrangementKind, ProductSnapshot productData = null)
        {
            var arrangementRequest = new ArrangementRequest();

            switch (arrangementKind)
            {
            case ArrangementKind.TermLoan:
                var termLoanRequest = new TermLoanRequest
                {
                    Amount                        = parameters.Amount ?? 0,
                    Currency                      = parameters.Currency,
                    Term                          = parameters.Term,
                    Annuity                       = parameters.Annuity ?? 0,
                    DownpaymentAmount             = parameters.DownpaymentAmount ?? 0,
                    Napr                          = parameters.InterestRate ?? 0,
                    RepaymentPeriod               = parameters.RepaymentPeriod,
                    RepaymentPeriodStartDate      = parameters.RepaymentPeriodStartDate,
                    GracePeriod                   = parameters.GracePeriod,
                    GracePeriodStartDate          = parameters.GracePeriodStartDate,
                    DrawdownPeriod                = parameters.DrawdownPeriod,
                    DrawdownPeriodStartDate       = parameters.DrawdownPeriodStartDate,
                    MaturityDate                  = parameters.MaturityDate,
                    DownpaymentPercentage         = parameters.DownpaymentPercentage,
                    InvoiceAmount                 = parameters.InvoiceAmount ?? 0,
                    IsRefinancing                 = parameters.IsRefinancing ?? false,
                    RepaymentType                 = parameters.RepaymentType,
                    InstallmentScheduleDayOfMonth = parameters.InstallmentScheduleDayOfMonth
                };
                arrangementRequest = termLoanRequest;
                break;

            case ArrangementKind.CardAccessArrangement:
                arrangementRequest = new CardAccessArrangementRequest();
                break;

            case ArrangementKind.CreditCardFacility:
                var creditCardFacilityRequest = new CreditCardFacilityRequest
                {
                    Amount                     = parameters.Amount ?? 0,
                    Currency                   = parameters.Currency,
                    Napr                       = parameters.InterestRate ?? 0,
                    Term                       = Utility.GetMonthsFromPeriod(parameters.Term).ToString(),
                    MaturityDate               = parameters.MaturityDate,
                    RevolvingPercentage        = parameters.RevolvingPercentage ?? 0,
                    MinimalRepaymentPercentage = productData?.MinimalRepaymentPercentage ?? 0,
                    MinimalRepaymentAmount     = new Currency
                    {
                        Amount = productData?.MinimalRepaymentAmount?.Amount ?? 0,
                        Code   = productData?.MinimalRepaymentAmount?.Code ?? "EUR"
                    },
                    RepaymentType = parameters.RepaymentType,
                    InstallmentScheduleDayOfMonth = parameters.InstallmentScheduleDayOfMonth
                };
                arrangementRequest = creditCardFacilityRequest;
                break;

            case ArrangementKind.CreditFacility:
                var creditFacilityRequest = new CreditFacilityRequest
                {
                    Amount                 = parameters.Amount ?? 0,
                    Currency               = parameters.Currency,
                    Napr                   = parameters.InterestRate ?? 0,
                    MaturityDate           = parameters.MaturityDate,
                    MinimalRepaymentAmount = new Currency
                    {
                        Amount = productData?.MinimalRepaymentAmount?.Amount ?? 0,
                        Code   = productData?.MinimalRepaymentAmount?.Code ?? "EUR"
                    }
                };
                arrangementRequest = creditFacilityRequest;
                break;

            case ArrangementKind.CurrentAccount:
                var currentAccountRequest = new CurrentAccountRequest
                {
                    Currency = parameters.Currency,
                    Napr     = parameters.InterestRate ?? 0
                };
                arrangementRequest = currentAccountRequest;
                break;

            case ArrangementKind.DemandDeposit:
                var demandDepositRequest = new DemandDepositRequest
                {
                    Currency = parameters.Currency,
                    Napr     = parameters.InterestRate ?? 0
                };
                arrangementRequest = demandDepositRequest;
                break;

            case ArrangementKind.ElectronicAccessArrangement:
                arrangementRequest = new ElectronicAccessArrangementRequest();
                break;

            case ArrangementKind.OtherProductArrangement:
                arrangementRequest = new OtherProductArrangementRequest();
                break;

            case ArrangementKind.OverdraftFacility:
                var overdraftFacilityRequest = new OverdraftFacilityRequest
                {
                    Amount        = parameters.Amount ?? 0,
                    Currency      = parameters.Currency,
                    Term          = Utility.GetMonthsFromPeriod(parameters.Term).ToString(),
                    Napr          = parameters.InterestRate ?? 0,
                    MaturityDate  = parameters.MaturityDate,
                    RepaymentType = parameters.RepaymentType,
                    InstallmentScheduleDayOfMonth = parameters.InstallmentScheduleDayOfMonth
                };
                arrangementRequest = overdraftFacilityRequest;
                break;

            case ArrangementKind.SecuritiesArrangement:
                arrangementRequest = new SecuritiesArrangementRequest();
                break;

            case ArrangementKind.TermDeposit:
                var termDepositRequest = new TermDepositRequest
                {
                    Amount       = parameters.Amount ?? 0,
                    Currency     = parameters.Currency,
                    Term         = parameters.Term,
                    Napr         = parameters.InterestRate ?? 0,
                    MaturityDate = parameters.MaturityDate
                };
                arrangementRequest = termDepositRequest;
                break;

            case ArrangementKind.Abstract:
                arrangementRequest = new AbstractArrangementRequest
                {
                    IsAbstractOrigin = true
                };
                break;

            case ArrangementKind.CreditLine:
                var creditLineRequest = new CreditLineRequest
                {
                    Amount   = parameters.Amount ?? 0,
                    Currency = parameters.Currency,
                    Term     = parameters.Term
                };
                arrangementRequest = creditLineRequest;
                break;

            default:
                arrangementRequest = new ArrangementRequest();
                break;
            }
            arrangementRequest.Conditions      = parameters.Conditions;
            arrangementRequest.Periods         = parameters.ScheduledPeriods;
            arrangementRequest.CalculationDate = parameters.CalculationDate;
            return(arrangementRequest);
        }
        private ArrangementRequest CalculateBySimpleCalculation(ArrangementRequest request, PriceCalculationParameters priceCalculationParameters)
        {
            if (!(request is FinanceServiceArrangementRequest))
            {
                return(request);
            }
            var priceCalc = (OfferPriceCalculation)_serviceProvider.GetService(typeof(OfferPriceCalculation));
            var priceArrangementRequest = priceCalc.CalculatePriceBySimpleCalculation(request, priceCalculationParameters).Result;

            request.Conditions = priceArrangementRequest.Conditions;
            priceCalculationParameters.InterestRates   = request.Conditions.InterestRates;
            priceCalculationParameters.Fees            = request.Conditions.Fees;
            priceCalculationParameters.OtherConditions = request.Conditions.Other;
            var basicCalculation = Mapper.Map <ArrangementRequest, SimpleLoanCalculationRequest>(request);

            basicCalculation.Fees      = new List <FeeEntry>();
            basicCalculation.StardDate = new DateTime(basicCalculation.StardDate.Year, basicCalculation.StardDate.Month, basicCalculation.StardDate.Day, 0, 0, 0);
            priceCalculationParameters.Fees.ForEach(x =>
            {
                basicCalculation.Fees.Add(new FeeEntry
                {
                    Kind                 = x.Kind,
                    Name                 = x.Title,
                    Frequency            = x.Frequency,
                    Percentage           = x.Percentage,
                    Currency             = x.FixedAmount?.Code ?? "",
                    FixedAmount          = x.FixedAmount?.Amount ?? 0,
                    LowerLimit           = x.LowerLimit?.Amount ?? 0,
                    UpperLimit           = x.UpperLimit?.Amount ?? 0,
                    ServiceCode          = x.ServiceCode,
                    Date                 = basicCalculation.StardDate,
                    CalculationBasisType = CalculationBasisType.AccountBalance
                });
            });

            basicCalculation.RegularInterest = priceCalculationParameters.InterestRates
                                               .Where(i => i.Currencies.Contains(priceCalculationParameters.Currency) && i.Kind == InterestRateKinds.RegularInterest)
                                               .Select(x => new InterestRateEntry
            {
                Date           = basicCalculation.StardDate,
                RatePercentage = (double)x.CalculatedRate,
                IsCompound     = x.IsCompound,
                CalendarBasis  = x.CalendarBasis,
                Name           = x.Title,
                RateUnitOfTime = Domain.Calculations.SimpleUnitOfTime.Y
            })
                                               .ToList();

            if (basicCalculation.RegularInterest.Count == 0)
            {
                throw new NotImplementedException("Interest rate is not in product currency");
            }

            var conversionMethod = _configurationService.GetEffective("offer/exposure/currency-conversion-method", "Buy to middle").Result;

            basicCalculation.FeeCurrencyConversionMethod = conversionMethod;

            if (basicCalculation.InstallmentSchedule.FrequencyPeriod == 0)
            {
                basicCalculation.InstallmentSchedule.FrequencyPeriod     = 1;
                basicCalculation.InstallmentSchedule.FrequencyUnitOfTime = SimpleUnitOfTime.M;
            }

            if (basicCalculation.Amount > 0 && basicCalculation.Annuity > 0 && basicCalculation.NumberOfInstallments == 0)
            {
                basicCalculation.CalculationTarget    = CalculationTarget.Term;
                basicCalculation.NumberOfInstallments = 0;
            }
            else if (basicCalculation.Annuity > 0 && basicCalculation.NumberOfInstallments > 0 && basicCalculation.Amount == 0)
            {
                basicCalculation.CalculationTarget = CalculationTarget.Amount;
            }
            else
            {
                basicCalculation.CalculationTarget = CalculationTarget.Annuity;
                basicCalculation.Annuity           = 0;
            }


            var adjustFirstInst = _configurationService.GetEffective("offer/calculation/adjust-first-installment", "false").Result;

            basicCalculation.AdjustFirstInstallment = Boolean.Parse(adjustFirstInst);

            var resultBasicCalculation = CalculateInstallmentPlan(basicCalculation);

            if (request is TermLoanRequest termLoanRequest && resultBasicCalculation != null)
            {
                termLoanRequest.Annuity                       = resultBasicCalculation.Annuity;
                termLoanRequest.Amount                        = resultBasicCalculation.Amount;
                termLoanRequest.Eapr                          = resultBasicCalculation.APR;
                termLoanRequest.InstallmentPlan               = resultBasicCalculation.Rows;
                termLoanRequest.NumberOfInstallments          = resultBasicCalculation.NumberOfInstallments;
                termLoanRequest.InstallmentPlan               = resultBasicCalculation.Rows;
                termLoanRequest.RepaymentType                 = basicCalculation.RepaymentType;
                termLoanRequest.InstallmentScheduleDayOfMonth = basicCalculation.InstallmentSchedule?.DayOfMonth ?? 1;
                if (basicCalculation.CalculationTarget == CalculationTarget.Term)
                {
                    termLoanRequest.Term = resultBasicCalculation.NumberOfInstallments.ToString();
                }
            }
        public async Task <IActionResult> UpdateArrangementRequestsForApplication([FromRoute] long applicationNumber, [FromRoute] int arrangementRequestId, [FromBody] ArrangementRequest command)
        {
            var updateArrangementRequest = new UpdateArrangementRequestCommand
            {
                ArrangementRequest   = command,
                ApplicationNumber    = applicationNumber,
                ArrangementRequestId = arrangementRequestId
            };
            var updateCustomerCommand = new IdentifiedCommand <UpdateArrangementRequestCommand, CommandStatus <bool> >(updateArrangementRequest, new Guid());

            var commandResult = await _mediator.Send(updateCustomerCommand);

            if (commandResult.CommandResult == StandardCommandResult.OK)
            {
                return(Ok());
            }
            else if (commandResult.CommandResult == StandardCommandResult.NOT_FOUND)
            {
                return(NotFound());
            }
            else if (commandResult.CommandResult == StandardCommandResult.BAD_REQUEST)
            {
                return(BadRequest(commandResult.Exception.Message));
            }
            else
            {
                return(StatusCode(500));
            }
        }
        public async Task <ArrangementRequest> CalculatePrice(Application application, ArrangementRequest request)
        {
            var calcParams = request.GetPriceCalculationParameters(application);

            return(await CalculatePrice(request, calcParams));
        }
Exemple #23
0
        private CalculateInstallmentPlanRequestCS AppendFees(CalculateInstallmentPlanRequestCS request, ArrangementRequest arrangementRequest)
        {
            // TODO Trigger price presentation before appending fees
            var fees = arrangementRequest?.Conditions.Fees;

            var originationFee = fees.FirstOrDefault(f => f.Kind == FeeConditionKind.OriginationFee);

            if (originationFee != null)
            {
                request.OriginationFeeFixedAmount = (double)originationFee.CalculatedFixedAmount;
                // request.OriginationFeeFixedAmountLcl ???
                request.OriginationFeeLowerLimit = (double)originationFee.CalculatedLowerLimit;
                //request.OriginationFeeLowerLimitLclValAmount
                request.OriginationFeeUpperLimit = (double)originationFee.CalculatedUpperLimit;
                //request.OriginationFeeUpperLimitLclValAmount
                request.OriginationFeePercentage = (double)originationFee.CalculatedPercentage;
                //request.OriginationFeeCapitalization
            }

            var managementFee = fees.FirstOrDefault(f => f.Kind == FeeConditionKind.ManagementFee);

            if (managementFee != null)
            {
                // TODO resolve this fields
                //request.ExcludeManagementFeeFromEAPR
                //request.FirstManagementFeeDate
                //request.IncludeManagementFeeInAnnuity
                switch (managementFee.Frequency)
                {
                case FeeConditionFrequency.Monthly:
                    request.ManagementFeeCalculationFrequencyPeriod = 1;
                    break;

                case FeeConditionFrequency.Quarterly:
                    request.ManagementFeeCalculationFrequencyPeriod = 3;
                    break;

                case FeeConditionFrequency.Semiyearly:
                    request.ManagementFeeCalculationFrequencyPeriod = 6;
                    break;

                case FeeConditionFrequency.Yearly:
                    request.ManagementFeeCalculationFrequencyPeriod = 12;
                    break;

                default:
                    // TODO What to do if it is event trigered or something similar? (invalid data so maybe throw an error?s)
                    request.ManagementFeeCalculationFrequencyPeriod = 12;
                    break;
                }
                request.ManagementFeeCalculationFrequencyUnitOfTime = CalculationService.Services.SimpleUnitOfTime.M;
                request.ManagementFeeLowerLimit = (double)managementFee.CalculatedLowerLimit;
                request.ManagementFeePercentage = (double)managementFee.CalculatedPercentage;
            }
            return(request);
        }
        public async Task <IActionResult> AddArrangementRequestsForApplication([FromRoute] long applicationNumber, [FromBody] ArrangementRequest command)
        {
            var addArrangementRequest = new AddArrangementRequestCommand
            {
                ArrangementRequest = command,
                ApplicationNumber  = applicationNumber,
            };
            bool?commandResult;

            commandResult = await _mediator.Send(addArrangementRequest);

            return(commandResult.HasValue ? commandResult.Value ? (IActionResult)Ok() : (IActionResult)BadRequest() : NotFound());
        }
Exemple #25
0
        public async Task <CommandStatus <bool> > Handle(UpdateArrangementRequestCommand message, CancellationToken cancellationToken)
        {
            this._logger.LogInformation("handle u command handleru");
            message.ArrangementRequest.ApplicationId        = message.ApplicationNumber;
            message.ArrangementRequest.ArrangementRequestId = message.ArrangementRequestId;
            ArrangementRequest request = _arrangementRequestRepository.GetArrangementRequest(message.ApplicationNumber, message.ArrangementRequestId);
            var conversionMethod       = _configurationService.GetEffective("offer/fee-currency-conversion-method", "Buy to middle").Result;

            if (request == null)
            {
                _logger.LogWarning("Tried to update unexisting arrangement request with application number: {0} and arrangement request id: {1}",
                                   message.ApplicationNumber, message.ArrangementRequestId);
                var e = new Exception(string.Format("Tried to update unexisting arrangement request with application number: {0} and arrangement request id: {1}",
                                                    message.ApplicationNumber, message.ArrangementRequestId));
                return(new CommandStatus <bool> {
                    Result = false, CommandResult = StandardCommandResult.BAD_REQUEST, Exception = e
                });
            }
            if (message.ArrangementRequest is TermLoanRequest termRequest &&
                termRequest.DisbursementsInfo != null && termRequest.DisbursementsInfo.Any())
            {
                var amountToBeChecked = termRequest.InvoiceAmount > 0 ? termRequest.InvoiceAmount : termRequest.Amount;
                CurrencyConverter currencyConverter = new CurrencyConverter();
                decimal           sumOfDisbursementsInPrimaryCurrency = 0;
                foreach (var item in termRequest.DisbursementsInfo)
                {
                    if (item != null && item.Amount != null)
                    {
                        continue;
                    }

                    if (item.Amount.Code == termRequest.Currency)
                    {
                        sumOfDisbursementsInPrimaryCurrency += item.Amount.Amount;
                    }
                    else
                    {
                        sumOfDisbursementsInPrimaryCurrency += currencyConverter.CurrencyConvert(item.Amount.Amount,
                                                                                                 item.Amount.Code,
                                                                                                 termRequest.Currency,
                                                                                                 DateTime.Today.ToString("o", CultureInfo.InvariantCulture),
                                                                                                 conversionMethod);
                    }

                    if (sumOfDisbursementsInPrimaryCurrency > amountToBeChecked)
                    {
                        _logger.LogWarning("Sum of disbursement info entries: {0}{2} is larger than invoice(credit) amount: {1}{2}", sumOfDisbursementsInPrimaryCurrency, amountToBeChecked, termRequest.Currency);
                        var e = new Exception(string.Format("Sum of disbursement info is above limits (invoice amount)"));
                        return(new CommandStatus <bool> {
                            Result = false, CommandResult = StandardCommandResult.BAD_REQUEST, Exception = e
                        });
                    }
                }
            }
            message.ArrangementRequest.InstallmentPlan = request.InstallmentPlan;
            if (request.ProductCode == message.ArrangementRequest.ProductCode)
            {
                message.ArrangementRequest.ProductSnapshot = request.ProductSnapshot;
                message.ArrangementRequest.ProductName     = request.ProductName;
            }
            else
            {
                return(new CommandStatus <bool> {
                    Result = false, CommandResult = StandardCommandResult.BAD_REQUEST, Exception = new Exception("An error occurred while updating arrangment - product code is wrong")
                });
                //var getProductData = new IdentifiedCommand<GetProductDataCommand, ProductData>(
                //    new GetProductDataCommand { ProductCode = message.ArrangementRequest.ProductCode }, new Guid());
                //ProductData productData = await _mediator.Send(getProductData);
                //ProductSnapshot snapshot = Mapper.Map<ProductData, ProductSnapshot>(productData);
                //message.ArrangementRequest.ProductSnapshot = snapshot;
                //message.ArrangementRequest.ProductName = snapshot.Name;
            }

            OfferApplication application =
                await _applicationRepository.GetAsync(message.ArrangementRequest.ApplicationId);

            application.PreferencialPrice = priceCalculator.HasPreferentialPrice(message.ArrangementRequest.Conditions);

            // Arrangement conditions
            request.Conditions = message.ArrangementRequest.Conditions;

            var priceCalculationParameters = request.GetPriceCalculationParameters(application);

            /*if (additionalProperties != null && additionalProperties.Keys.Count() > 0)
             * {
             *  priceCalculationParameters.AdditionalProperties = priceCalculationParameters.AdditionalProperties ?? new Dictionary<string, JToken>();
             *  priceCalculationParameters.AdditionalProperties = priceCalculationParameters.AdditionalProperties
             *      .Concat(additionalProperties
             *              .Where(k => !priceCalculationParameters.AdditionalProperties.ContainsKey(k.Key))
             *              .ToDictionary(k => k.Key, v => v.Value))
             *      .ToDictionary(k => k.Key, v => v.Value);
             * }*/

            message.ArrangementRequest = _calculatorProvider.Calculate(message.ArrangementRequest, application);
            //message.ArrangementRequest.CalculateOffer(priceCalculationParameters, priceCalculator, conversionMethod);

            await _arrangementRequestRepository.UpdateArrangementRequest(message.ArrangementRequest);

            var messageObj = _messageEventFactory.CreateBuilder("offer", "product-selection-changed")
                             .AddHeaderProperty("application-number", application.ApplicationNumber);

            messageObj = messageObj.AddBodyProperty("product-code", application.ProductCode)
                         .AddBodyProperty("product-name", application.ProductName);
            _eventBus.Publish(messageObj.Build());

            bool result = await _arrangementRequestRepository.UnitOfWork.SaveEntitiesAsync();

            await _auditClient.WriteLogEntry(AuditLogEntryAction.Update, AuditLogEntryStatus.Success, "arrangement", message.ApplicationNumber.ToString(), "Arrangement has been updated " + message.ArrangementRequestId, new { });

            StandardCommandResult commandResult = result ? StandardCommandResult.OK : StandardCommandResult.BAD_REQUEST;

            return(new CommandStatus <bool> {
                Result = result, CommandResult = commandResult
            });
        }
Exemple #26
0
 public GetProductConditionsCommand(ArrangementRequest arrangementRequest)
 {
     ArrangementRequest = arrangementRequest;
 }
        //
        // GET: /ArrangementRequests/Delete/5

        public ActionResult Delete(int id)
        {
            ArrangementRequest revisionarreglo = db.ArrangementRequests.Find(id);

            return(View(revisionarreglo));
        }
Exemple #28
0
 public bool AddArrangementRequest(ArrangementRequest request)
 {
     _context.Add(request);
     return(true);
 }
        //
        // GET: /ArrangementRequests/Details/5

        public ViewResult Details(int id)
        {
            ArrangementRequest revisionarreglo = db.ArrangementRequests.Find(id);

            return(View(revisionarreglo));
        }