예제 #1
0
        public async Task <List <ArrangementRequest> > ResolveAdditionalProduct(OfferApplication application, ApplyForProductDefinition message)
        {
            #region Fetch additional product settings from configuration
            var additionalProductSettings = await _configurationService.GetEffective <AdditionalProductSettings>("offer/new-customer/default-addon-settings");

            if (string.IsNullOrEmpty(additionalProductSettings?.ProductCode))
            {
                _logger.LogWarning("ProductCode for Additional Product Settings doesn't exist. Using additional product for new customer is skipped.");
                return(null);
            }
            #endregion

            try
            {
                // Potencijalni problem - kreiranje ArrangementRequestInitializationParameters
                var parameters = new ArrangementRequestInitializationParameters
                {
                    CustomerNumber = message.CustomerNumber,
                    Currency       = message.Currency,
                    ProductCode    = additionalProductSettings.ProductCode
                };
                return(await _requestFactory.AddToApplication(application, additionalProductSettings.ProductCode, parameters));
            }
            catch (HttpRequestException)
            {
                _logger.LogInformation("Additional product for product code {ProductCode} doesn't exist. Using additional product for new customer is skipped.",
                                       additionalProductSettings.ProductCode);
                return(null);
            }
        }
예제 #2
0
        public async Task <List <ArrangementRequest> > AddToApplication(OfferApplication application, string productCode,
                                                                        ArrangementRequestInitializationParameters parameters)
        {
            application.ArrangementRequests = application.ArrangementRequests ?? new List <ArrangementRequest>();
            // Get product data
            var productData = await _productService.GetProductData(productCode, "documentation", application.CustomerNumber);

            if (!ShouldAddProduct(application, productData))
            {
                _logger.LogInformation("Product not added because it doesn't satisfies all conditions");
                return(null);
            }
            var response = new List <ArrangementRequest>();
            // Bootstrap arr request
            var arrangementRequest = await BootstrapArrangementRequest(parameters, productData, application);

            application.ArrangementRequests.Add(arrangementRequest);
            response.Add(arrangementRequest);

            // Resolve bundle
            if (!(arrangementRequest is AbstractArrangementRequest))
            {
                var resolved = await ResolveBundleComponents(application, productData);

                if (resolved != null)
                {
                    response.AddRange(resolved);
                }
            }
            PerformCalculation(application, arrangementRequest);

            return(response);
        }
예제 #3
0
        private async Task <List <ArrangementRequest> > AddAbstractProduct(OfferApplication application,
                                                                           BundledProductInfo bundleInfo, int numberOfInstances)
        {
            // If abstract product contains product which is singleton and is already added earlier before,
            // it will be skipped but not some other product will be added instead of it in order to fulfill number of instances

            // Get product data
            var productData = await _productService.GetProductData(bundleInfo.ProductCode, "documentation", application.CustomerNumber);

            if (productData.Kind != ProductKinds.AbstractProduct)
            {
                return(null);
            }
            var response = new List <ArrangementRequest>();
            var variants = productData.Variants?.Split(",") ?? new string[0];

            var instancesToCreate = Math.Min(numberOfInstances, variants.Count());
            var parameters        = new ArrangementRequestInitializationParameters
            {
                IsAbstractOrigin = true
            };
            int i;

            for (i = 0; i < instancesToCreate; i++)
            {
                var resolved = await AddBundleComponentToApplication(application, variants[i], bundleInfo, bundleInfo.ProductCode, parameters);

                if (resolved != null)
                {
                    response.AddRange(resolved);
                }
            }
            if (variants.Count() > i)
            {
                for (; i < variants.Count(); i++)
                {
                    var resolved = await AddBundleComponentToApplication(application, variants[i], bundleInfo, bundleInfo.ProductCode, parameters);

                    if (resolved != null)
                    {
                        foreach (var item in resolved)
                        {
                            item.Enabled = false;
                        }
                    }
                    if (resolved != null)
                    {
                        response.AddRange(resolved);
                    }
                }
            }
            return(response);
        }
예제 #4
0
        public async Task <List <ArrangementRequest> > AddBundleComponentToApplication(OfferApplication application, string productCode,
                                                                                       BundledProductInfo bundleInfo, string parentProductCode,
                                                                                       ArrangementRequestInitializationParameters parameters = null)
        {
            application.ArrangementRequests = application.ArrangementRequests ?? new List <ArrangementRequest>();
            // Get product data
            ProductSnapshot productData;

            try
            {
                productData = await _productService.GetProductData(productCode, "documentation", application.CustomerNumber);
            }
            catch
            {
                productData = null;
            }
            if (!ShouldAddProduct(application, productData))
            {
                _logger.LogInformation("Bundled product not added because it doesn't satisfies all conditions");
                return(null);
            }
            if (bundleInfo.ProductKind != ProductKinds.AbstractProduct && productData.Kind != bundleInfo.ProductKind)
            {
                var e = new Exception("Product Kinds on Bundle Info and on Product Data are different.");
                _logger.LogError(e, "Error occurred while adding bundle component " + bundleInfo.ProductCode +
                                 " from parent product " + parentProductCode + " to application");
                throw e;
            }
            var response = new List <ArrangementRequest>();
            // Bootstrap arr request
            var arrangementRequest = await BootstrapArrangementRequest(parameters, productData, application);

            arrangementRequest.ProductName = arrangementRequest.IsAbstractOrigin ?
                                             arrangementRequest.ProductName : (bundleInfo.ProductName ?? arrangementRequest.ProductName);
            arrangementRequest.ParentProductCode = parentProductCode;
            arrangementRequest.BundleInfo        = bundleInfo;
            arrangementRequest.ProductCode       = productData.ProductCode;
            application.ArrangementRequests.Add(arrangementRequest);
            arrangementRequest.IsOptional = IsOptional(bundleInfo);
            response.Add(arrangementRequest);

            // Resolve bundle
            if (!(arrangementRequest is AbstractArrangementRequest))
            {
                // TODO Reconsider snapshoting unresolved nested bundles instead of ignoring them (how they wil be solved afterwards?)
                var resolveNestedBundles = (await _configurationService.GetEffective("offer/bundled-products/resolve-nested", "false"))
                                           .Equals("true");
                if (resolveNestedBundles)
                {
                    var resolved = await ResolveBundleComponents(application, productData);

                    if (resolved != null)
                    {
                        response.AddRange(resolved);
                    }
                }
            }
            PerformCalculation(application, arrangementRequest);
            return(response);
        }
예제 #5
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);
        }
예제 #6
0
 public ArrangementRequest GetForProductKind(ArrangementRequestInitializationParameters parameters, ProductSnapshot productData = null)
 {
     return(GetForArrangementKind(parameters, OfferUtility.GetArrangmentKindByProductKind(productData.Kind), productData));
 }
예제 #7
0
        public ArrangementRequestInitializationParameters GetInitializationParametersFromProduct(ProductSnapshot productData,
                                                                                                 ArrangementRequestInitializationParameters parameters)
        {
            if (productData == null)
            {
                return(null);
            }
            parameters               = parameters ?? new ArrangementRequestInitializationParameters();
            parameters.Amount        = parameters.Amount ?? productData.DefaultParameters?.Amount ?? ((productData.MinimalAmount?.Amount ?? 0) + (productData.MaximalAmount?.Amount ?? 2)) / 2;
            parameters.Term          = parameters.Term ?? productData.DefaultParameters?.Term ?? productData.MaximalTerm;
            parameters.Currency      = parameters.Currency ?? productData.PrimaryCurrency ?? productData.MinimalAmount?.Code ?? productData.AllowedCurrencies?.FirstOrDefault();
            parameters.IsRefinancing = parameters.IsRefinancing ?? productData.DefaultParameters?.IsRefinancing ?? (string.IsNullOrEmpty(productData.Refinancing) ? false : productData.Refinancing.Equals("always"));

            parameters.DownpaymentPercentage = parameters.DownpaymentPercentage ?? productData.DefaultParameters?.DownpaymentPercentage ?? (productData.MinimalDownpaymentPercentage == 0 ? 20 : productData.MinimalDownpaymentPercentage);
            parameters.InvoiceAmount         = parameters.InvoiceAmount ?? productData.DefaultParameters?.InvoiceAmount ?? (parameters.Amount / (1 - parameters.DownpaymentPercentage / 100));
            parameters.DownpaymentAmount     = parameters.InvoiceAmount == 0 ? 0 : parameters.InvoiceAmount - parameters.Amount;

            parameters.ProductCode         = parameters.ProductCode ?? productData.ProductCode;
            parameters.RevolvingPercentage = parameters.RevolvingPercentage ?? productData.DefaultParameters?.RevolvingPercentage ?? (string.IsNullOrEmpty(productData.AvailableRevolvingPercentage) ? (decimal?)null : decimal.Parse(productData.AvailableRevolvingPercentage.Split(",").First()));

            return(parameters);
        }
예제 #8
0
        public async Task <ArrangementRequest> BootstrapArrangementRequest(ArrangementRequestInitializationParameters parameters,
                                                                           ProductSnapshot productData, OfferApplication application)
        {
            #region Create initial
            ArrangementKind?arrangementKind = OfferUtility.GetArrangmentKindByProductKind(productData.Kind);
            parameters = GetInitializationParametersFromProduct(productData, parameters) ?? new ArrangementRequestInitializationParameters();
            var arrangementRequest = GetForProductKind(parameters, productData);
            arrangementRequest.ArrangementRequestId = GetNextRequestIdForApplication(application);
            arrangementRequest.Application          = application;
            arrangementRequest.ProductSnapshot      = productData;
            arrangementRequest.ArrangementKind      = arrangementKind;
            arrangementRequest.ProductName          = arrangementRequest.ProductName ?? productData.Name;
            arrangementRequest.CalculationDate      = arrangementRequest.CalculationDate ?? DateTime.UtcNow;
            arrangementRequest.ProductCode          = parameters.ProductCode ?? productData.ProductCode;
            arrangementRequest.Conditions           = parameters.Conditions;
            arrangementRequest.Options          = parameters.ProductOptions;
            arrangementRequest.IsAbstractOrigin = parameters.IsAbstractOrigin ?? false;
            arrangementRequest.RepaymentType    = parameters.RepaymentType ?? null;
            arrangementRequest.InstallmentScheduleDayOfMonth = parameters.InstallmentScheduleDayOfMonth;
            #endregion
            arrangementRequest.ProductSnapshotDb = await _productSnapshotRepository.PostProductSnapshot(productData);

            if (arrangementRequest is FinanceServiceArrangementRequest ara)
            {
                #region Resolve for Finance service
                arrangementRequest = AddCollateralRequirements(ara);
                var conversionMethod = _configurationService.GetEffective("offer/fee-currency-conversion-method", "Buy to middle").Result;
                var domesticCurrency = _configurationService.GetEffective("domestic-currency", "RSD").Result;

                if (domesticCurrency != null)
                {
                    if (domesticCurrency == parameters.Currency)
                    {
                        ara.AmountInDomesticCurrency = parameters.Amount ?? 0;
                    }
                    else if (ara.Amount != 0)
                    {
                        var financial = (FinanceServiceArrangementRequest)arrangementRequest;
                        CurrencyConverter currencyConverter = new CurrencyConverter();
                        financial.AmountInDomesticCurrency = currencyConverter.CurrencyConvert(financial.Amount, financial.Currency,
                                                                                               domesticCurrency, DateTime.Today.ToString("o", CultureInfo.InvariantCulture), conversionMethod);
                    }
                }
                #endregion
            }


            if (arrangementRequest is OverdraftFacilityRequest)
            {
                #region Resolve accounts for overdraft
                var arrangementList = await _arrangementService.GetArrangements(parameters.CustomerNumber);

                var arr = arrangementList?.FirstOrDefault();
                if (arr != null)
                {
                    List <ArrangementAccountInfo> arrangementAccounts = new List <ArrangementAccountInfo>();
                    JArray accountList     = (JArray)arr["accounts"];
                    var    primaryAccounts = accountList.Where(x => x["role-kind"].ToString().Equals("primary-account")).ToList();
                    foreach (var account in primaryAccounts)
                    {
                        var accountNumber = account["account-number"].ToString();
                        ArrangementAccountInfo newAccount = new ArrangementAccountInfo
                        {
                            AccountNumber = accountNumber,
                            RoleKind      = ArrangementAccountRoleKind.SettlementAccount
                        };
                        arrangementAccounts.Add(newAccount);
                    }
                    arrangementRequest.Accounts = arrangementAccounts;
                }
                #endregion
            }

            if (!string.IsNullOrEmpty(parameters.CustomerNumber))
            {
                #region Resolve campaigns
                var leadList = await _campaignService.GetCampaigns(parameters.CustomerNumber);

                var productCampaign = leadList?.Leads?.Where(l => l.ProductCode == arrangementRequest.ProductCode).FirstOrDefault();
                arrangementRequest.ProductSnapshot.Campaign = productCampaign;
                arrangementRequest.Campaign = productCampaign;
                #endregion
            }

            if (!parameters.MaturityDate.HasValue && arrangementRequest.IsFinanceService() && parameters.Term != null)
            {
                FinanceServiceArrangementRequest fsr = arrangementRequest as FinanceServiceArrangementRequest;
                fsr.MaturityDate = Utility.GetEndDateFromPeriod(parameters.Term);
            }
            return(arrangementRequest);
        }