Exemplo n.º 1
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);
        }
Exemplo n.º 2
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);
            }
        }
Exemplo n.º 3
0
        public async Task <List <ArrangementRequest> > ResolveBundleComponents(OfferApplication application, ProductSnapshot productData)
        {
            if (productData.BundledProducts == null || productData.BundledProducts.Count() == 0)
            {
                return(null);
            }
            application.OriginatesBundle = true;
            var response         = new List <ArrangementRequest>();
            var createIfOptional = (await _configurationService
                                    .GetEffective("offer/bundled-products/create-if-optional", "true")).Equals("true");

            foreach (var bundled in productData.BundledProducts)
            {
                var instancesToCreate = bundled.MinimalNumberOfInstances > 0 ? bundled.MinimalNumberOfInstances :
                                        (createIfOptional ? 1 : 0);
                if (bundled.ProductKind == ProductKinds.AbstractProduct)
                {
                    var resolved = await AddAbstractProduct(application, bundled, instancesToCreate);

                    if (resolved != null)
                    {
                        response.AddRange(resolved);
                    }
                }
                else
                {
                    for (int i = 0; i < instancesToCreate; i++)
                    {
                        var resolved = await AddBundleComponentToApplication(application, bundled.ProductCode, bundled, productData.ProductCode);

                        if (resolved != null)
                        {
                            if (createIfOptional && bundled.MinimalNumberOfInstances == 0)
                            {
                                foreach (var item in resolved)
                                {
                                    item.Enabled = false;
                                }
                            }
                            response.AddRange(resolved);
                        }
                    }
                    if (instancesToCreate == 0)
                    {
                        var resolved = await AddBundleComponentToApplication(application, bundled.ProductCode, bundled, productData.ProductCode);

                        foreach (var item in resolved)
                        {
                            item.Enabled = false;
                        }
                        if (resolved != null)
                        {
                            response.AddRange(resolved);
                        }
                    }
                }
            }
            return(response);
        }
Exemplo n.º 4
0
 public int GetNextRequestIdForApplication(OfferApplication application)
 {
     if (application.ArrangementRequests == null || application.ArrangementRequests.Count() == 0)
     {
         return(1);
     }
     return(application.ArrangementRequests.Max(r => r.ArrangementRequestId) + 1);
 }
Exemplo n.º 5
0
 private async Task <bool> CalculateExposuresForApplication(OfferApplication application, ExposureList exposureList)
 {
     try
     {
         if (application.ArrangementRequests == null)
         {
             application = await _applicationRepository.GetAsync(application.ApplicationId, "arrangement-requests");
         }
         var checkBalanceList       = _configurationService.GetEffective("offer/exposure/balance-arrangement-kinds", "term-loan").Result;
         var creditArrangementTypes = EnumUtils.GetEnumPropertiesForListString <ArrangementKind>("term-loan,overdraft-facility,credit-facility,credit-card-facility");
         var arrangements           = application.ArrangementRequests
                                      .Where(x => (x.Enabled ?? false) &&
                                             creditArrangementTypes.Contains(x.ArrangementKind.GetValueOrDefault()))
                                      .ToList();
         foreach (var arr in arrangements)
         {
             // due to abovementioned and selected arrangement kinds we can do this
             var financial  = (FinanceServiceArrangementRequest)arr;
             var termMonths = 0;
             if (!string.IsNullOrEmpty(financial.Term) && financial.Term.StartsWith("P"))
             {
                 termMonths = Utility.GetMonthsFromPeriod(financial.Term);
             }
             else if (!string.IsNullOrEmpty(financial.Term))
             {
                 termMonths = Convert.ToInt32(financial.Term);
             }
             string   riskCategory = ResolveRiskCategory(arr.ArrangementKind);
             Exposure exp          = new Exposure
             {
                 PartyId         = application.CustomerNumber,
                 CustomerName    = application.CustomerName,
                 ArrangementKind = arr.ArrangementKind,
                 Term            = financial.Term != null ? "P" + termMonths / 12 + "Y" + termMonths % 12 + "M" : "P0M",
                 isBalance       = checkBalanceList.Contains(StringExtensions.ToKebabCase(arr.ArrangementKind.ToString())) ? true : false,
                 AccountNumber   = arr.ApplicationNumber + "/" + arr.ArrangementRequestId,
                 Currency        = financial.Currency,
                 ExposureApprovedInSourceCurrency          = financial.Amount,
                 AnnuityInSourceCurrency                   = financial.TotalAnnuity,
                 ExposureOutstandingAmountInSourceCurrency = financial.Amount,
                 RiskCategory = riskCategory
             };
             if (arr.ArrangementKind == ArrangementKind.TermLoan)
             {
                 var termLoan = (TermLoanRequest)arr;
                 exp.AnnuityInSourceCurrency = termLoan.Annuity;
             }
             exposureList.Exposures.Add(exp);
         }
     }
     catch (Exception e)
     {
         _logger.LogError(e, "CalculateExposuresForApplication exception");
         throw e;
     }
     return(true);
 }
        public async Task <bool?> Handle(RecalculateArrangementRequestCommand message, CancellationToken cancellationToken)
        {
            //var conversionMethod = _configurationService.GetEffective("offer/fee-currency-conversion-method", "Buy to middle").Result;
            var arrangementRequest       = _arrangementRequestRepository.GetArrangementRequest(message.ApplicationNumber, message.ArrangementRequestId);
            OfferApplication application = await _applicationRepository.GetAsync(message.ApplicationNumber);

            _calculatorProvider.Calculate(arrangementRequest, application);
            //arrangementRequest.CalculateOffer(application, priceCalculator, conversionMethod);
            await _arrangementRequestRepository.UpdateArrangementRequest(arrangementRequest);

            return(await _arrangementRequestRepository.UnitOfWork.SaveEntitiesAsync());
        }
Exemplo n.º 7
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);
        }
Exemplo n.º 8
0
        private bool ShouldAddProduct(OfferApplication application, ProductSnapshot productData)
        {
            if (productData == null)
            {
                return(false);
            }
            // Jel treba ovo standalone da bude?. Proveriti
            if (!productData.IsSingleton)
            {
                return(true);
            }

            return(!application.ArrangementRequests.Any(r => r.ProductCode.Equals(productData.ProductCode)));
        }
        public async Task <DocumentationValidationResponse> Handle(RequiredDocumentationValidationCommand message, CancellationToken cancellationToken)
        {
            OfferApplication application = await _applicationRepository.GetAsync(message.ApplicationNumber,
                                                                                 "involved-parties,documents,arrangement-requests");

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

            application.Documents = application.Documents ?? new List <ApplicationDocument>();
            var res = _requiredDocumentationResolver.ResolveDocuments(application, message.Items);

            await _auditClient.WriteLogEntry(AuditLogEntryAction.Validate, AuditLogEntryStatus.Success, "documents", application.ApplicationNumber.ToString(), "Resolving documents", new { });

            return(res);
        }
Exemplo n.º 10
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();
         }
     }
 }
        private async Task <bool> CreateContentFolders(OfferApplication application)
        {
            try
            {
                await _contentService.CreateFolder("" + application.ApplicationNumber, "/offer", "folder", "application-documents-folder");
            }
            catch (Exception e)
            {
                _logger.LogError(e, "An error occurred while creating application folder for application {ApplicationNumber}", application.ApplicationNumber);
            }

            try
            {
                if (application.Documents != null)
                {
                    _logger.LogDebug("Create slots ");
                    var applicationDocuments = application.Documents.ToList();
                    foreach (var document in applicationDocuments)
                    {
                        var path = "/offer/" + document.ApplicationNumber;
                        try
                        {
                            await _contentService.CreateFolder("" + document.DocumentId, path, "folder", "generic-folder");
                        }
                        catch (Exception e)
                        {
                            _logger.LogError(e, "An error occurred while creating folder for document {DocumentId} on path {ContentPath}",
                                             document.DocumentId, path);
                        }
                    }
                }
            }
            catch (Exception e)
            {
                _logger.LogError(e, "An error occurred while creating documents folder for application {ApplicationNumber}", application.ApplicationNumber);
            }
            return(true);
        }
        private async Task <bool> HandleApplicationDocuments(OfferApplication application, InitiateOnlineOfferCommand message)
        {
            #region Adding documents for application
            List <ApplicationDocument> applicationDocuments = new List <ApplicationDocument>();
            application.Documents = new List <ApplicationDocument>();
            var getProductDocumentation = new IdentifiedCommand <GetProductDocumentationCommand, List <ProductDocumentation> >(
                new GetProductDocumentationCommand {
                ProductCode = message.ProductCode
            }, new Guid());
            List <ProductDocumentation> productDocuments = await _mediator.Send(getProductDocumentation);

            foreach (var document in productDocuments)
            {
                if (document.DocumentContextKind.Equals(DocumentContextKind.ApplicationEnum))
                {
                    var appDocument = Mapper.Map <ProductDocumentation, ApplicationDocument>(document);
                    applicationDocuments.Add(appDocument);
                }
                else if (document.DocumentContextKind.Equals(DocumentContextKind.PartyEnum) && application.InvolvedParties.Count() > 0)
                {
                    var customer    = application.InvolvedParties.FirstOrDefault(c => c.PartyRole.Equals(PartyRole.Customer));
                    var appDocument = Mapper.Map <ProductDocumentation, ApplicationDocument>(document);
                    if (customer != null)
                    {
                        appDocument.PartyId = customer.PartyId;
                    }

                    if (document.PartyRole.Equals(Domain.AggregatesModel.ApplicationAggregate.ProductModel.PartyRoleEnum.CustomerEnum) ||
                        (document.PartyRole.Equals(Domain.AggregatesModel.ApplicationAggregate.ProductModel.PartyRoleEnum.NewCustomerEnum) && string.IsNullOrEmpty(message.CustomerNumber)))
                    {
                        applicationDocuments.Add(appDocument);
                    }
                }
            }
            application.Documents.AddRange(applicationDocuments);
            #endregion
            return(true);
        }
        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);
            }
        }
Exemplo n.º 14
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
            });
        }
        private async Task <ArrangementRequestHandlingResponse> HandleArrangementRequests(OfferApplication application,
                                                                                          InitiateOnlineOfferCommand message)
        {
            #region handle main product inclusion
            var parameters      = Mapper.Map <InitiateOnlineOfferCommand, ArrangementRequestInitializationParameters>(message);
            var factoryResponse = await _requestFactory.AddToApplication(application, message.ProductCode, parameters);

            application.OriginatesBundle = factoryResponse.Any(r => r.BundleInfo != null);
            var arrangementRequest = factoryResponse.FirstOrDefault();
            arrangementRequest.IsOptional = false;
            #endregion

            if (arrangementRequest.IsFinanceService())
            {
                #region Check calculation
                var annuityIsDifferent = false;
                var error = false;
                try
                {
                    annuityIsDifferent = Math.Abs(Math.Round((((TermLoanRequest)arrangementRequest).Annuity - message.Annuity), 0)) > 0;
                }
                catch (Exception e)
                {
                    _logger.LogError(e, "An unknown error occured while checking calculated and provided annuity");
                    error = true;
                }
                if (message.Annuity > 0 && !error && annuityIsDifferent)
                {
                    var e = new InvalidCalculationException("Received and calculated annuity are not equal");
                    _logger.LogError(e, "Error in calculation: Received and calculated annuity are not equal");
                    throw e;
                }
                #endregion
                // Add additional product for new customer
                if (string.IsNullOrEmpty(application.CustomerNumber))
                {
                    var applyDefinition = Mapper.Map <InitiateOnlineOfferCommand, ApplyForProductDefinition>(message);
                    var resolved        = await _offerUtility.ResolveAdditionalProduct(application, applyDefinition);

                    if (resolved != null)
                    {
                        var additional = resolved.FirstOrDefault();
                        if (additional != null)
                        {
                            additional.IsOptional = false;
                        }
                        factoryResponse.AddRange(resolved);
                    }
                }
            }

            application.TermLimitBreached            = TermLimitsBreached(message.Term, arrangementRequest.ProductSnapshot);
            application.AmountLimitBreached          = AmountLimitsBreached(message.Amount, message.Currency, arrangementRequest.ProductSnapshot);
            arrangementRequest.OverrideProductLimits = false;
            if (application.TermLimitBreached || application.AmountLimitBreached)
            {
                arrangementRequest.OverrideProductLimits = true;
            }

            if (message.IsProposal)
            {
                if (!string.IsNullOrEmpty(arrangementRequest.ProductSnapshot.ProposalValidityPeriod))
                {
                    var validityProposalPeriod = arrangementRequest.ProductSnapshot.ProposalValidityPeriod;

                    DateTime expirationDate = Utility.GetEndDateFromPeriod(validityProposalPeriod, DateTime.UtcNow);
                    application.ExpirationDate = expirationDate;
                }
            }
            else if (!String.IsNullOrEmpty(arrangementRequest.ProductSnapshot.OfferValidityPeriod))
            {
                var validityPeriod = arrangementRequest.ProductSnapshot.OfferValidityPeriod;

                DateTime expirationDate = Utility.GetEndDateFromPeriod(validityPeriod, DateTime.UtcNow);
                application.ExpirationDate = expirationDate;
            }
            return(new ArrangementRequestHandlingResponse
            {
                FactoryResponse = factoryResponse,
                MainRequest = arrangementRequest
            });
        }
        private async Task <int> HandleParties(OfferApplication application, InitiateOnlineOfferCommand message)
        {
            // Checking active offers
            string activeStatuses = await _configurationService.GetEffective("offer/active-statuses", "draft,active,approved,accepted");

            List <ApplicationStatus> statusList = null;

            if (!string.IsNullOrEmpty(activeStatuses))
            {
                statusList = EnumUtils.GetEnumPropertiesForListString <ApplicationStatus>(activeStatuses);
            }
            var   rolesList = EnumUtils.GetEnumPropertiesForListString <PartyRole>("customer");
            Party party;

            int activeOffers;

            if (string.IsNullOrEmpty(message.CustomerNumber))
            {
                if (string.IsNullOrEmpty(message.EmailAddress))
                {
                    activeOffers = 0;
                }
                else
                {
                    activeOffers = _applicationRepository.CheckExistingOffersForProspect(message.Username, message.EmailAddress, statusList, rolesList).Count;
                }
                party = new IndividualParty
                {
                    GivenName                = message.GivenName,
                    Surname                  = message.Surname,
                    ParentName               = message.ParentName,
                    CustomerName             = message.GivenName + " " + message.Surname,
                    IdentificationNumberKind = message.IdentificationNumberKind,
                    IdentificationNumber     = message.IdentificationNumber,
                    EmailAddress             = message.EmailAddress,
                    MobilePhone              = message.MobilePhone,
                    Gender    = Gender.Unknown,
                    PartyRole = PartyRole.Customer,
                    Username  = message.Username
                };

                party.LegalAddress = new PostalAddress
                {
                    Coordinates = new Coordinates()
                };
                party.ContactAddress = new PostalAddress
                {
                    Coordinates = new Coordinates()
                };
                application.InvolvedParties = new List <Party> {
                    party
                };
                _logger.LogInformation("New customer: {givenName} {surname} ({emailAddress})", message.GivenName, message.Surname, message.EmailAddress);
            }
            else
            {
                activeOffers = _applicationRepository.CheckExistingOffersForCustomer(message.CustomerNumber, statusList, rolesList).Count;
                if (message.PartyKind == PartyKind.Organization)
                {
                    party = new OrganizationParty
                    {
                        CustomerNumber = message.CustomerNumber,
                        EmailAddress   = message.EmailAddress,
                        PartyKind      = PartyKind.Organization
                    };
                }
                else
                {
                    party = new IndividualParty
                    {
                        CustomerNumber = message.CustomerNumber,
                        EmailAddress   = message.EmailAddress
                    };
                }

                var partyData = await _partyDataService.GetPartyData(party);

                string defaultOrganizationUnit = await _configurationService.GetEffective("offer/default-organization-unit", null);

                if (!string.IsNullOrEmpty(message.AgentOrganizationUnit))
                {
                    application.OrganizationUnitCode = message.AgentOrganizationUnit;
                }
                else
                {
                    application.OrganizationUnitCode = partyData.OrganizationUnitCode ?? defaultOrganizationUnit;
                }

                application.InvolvedParties = new List <Party> {
                    party
                };

                //if (partyData is OrganizationParty orgParty && orgParty.Relationships.Count() > 0)
                //{
                //    List<Relationships> listRelationships = orgParty.Relationships;
                //    foreach (var item in listRelationships)
                //    {
                //        Party customerRepresentative;
                //        if (item.ToParty.Kind == PartyKind.Individual)
                //        {
                //            customerRepresentative = new IndividualParty
                //            {
                //                CustomerNumber = item.ToParty.Number.ToString(),
                //                PartyRole = PartyRole.AuthorizedPerson
                //            };
                //        }
                //        else
                //        {
                //            customerRepresentative = new OrganizationParty
                //            {
                //                CustomerNumber = item.ToParty.Number.ToString(),
                //                PartyRole = PartyRole.AuthorizedPerson
                //            };
                //        }

                //        var customerRelationship = await _partyDataService.GetPartyData(customerRepresentative);
                //        application.InvolvedParties.Add(customerRepresentative);
                //    }
                //}

                if (party.PartyRole == PartyRole.Customer)
                {
                    application.CustomerName   = partyData.CustomerName;
                    application.CustomerNumber = partyData.CustomerNumber;
                    party.EmailAddress         = partyData.EmailAddress;


                    if (string.IsNullOrEmpty(application.CountryCode) && party != null)
                    {
                        application.CountryCode = party.CountryOfResidence;
                    }
                    if (string.IsNullOrEmpty(application.PrefferedCulture) && party != null)
                    {
                        application.PrefferedCulture = party.PreferredCulture;
                    }
                }

                _logger.LogInformation("Existing customer: {customerNumber} ({emailAddress})", party.CustomerNumber, party.EmailAddress);
            }

            return(activeOffers);
        }
        public async Task <IntialOnlineOfferCommandResult> Handle(InitiateOnlineOfferCommand message, CancellationToken cancellationToken)
        {
            Console.WriteLine("Offer - IntialOnlineOfferCommandResult - Handle start !!!");
            var dateBeforeCall = DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ss.fff",
                                                          CultureInfo.InvariantCulture);

            Console.WriteLine("START {0}", dateBeforeCall);
            string defaultLoader = await _configurationService.GetEffective("offer/html/default-loader", "");

            var application = new OfferApplication
            {
                ArrangementRequests = new List <ArrangementRequest>(),
                Status            = ApplicationStatus.Draft,
                StatusInformation = new StatusInformation()
                {
                    Title = "Initiating...", Description = "We are initiating the application. Please wait.", Html = defaultLoader
                },
                RequestDate     = DateTime.UtcNow,
                ChannelCode     = await AppendChannel(message),
                ProductCode     = message.ProductCode,
                ProductName     = message.ProductName,
                Initiator       = message.Username,
                CollateralModel = message.CollateralModel,
                Phase           = EnumUtils.ToEnumString(ApplicationStatus.Draft)
            };

            application.LeadId = message.LeadId ?? application.LeadId;

            if (message.LeadId != null)
            {
                var app = await _applicationRepository.GetApplicationByLeadId(message.LeadId);

                if (app != null)
                {
                    return(new IntialOnlineOfferCommandResult {
                        ApplicationNumber = "", Result = CommandResult.LEAD_ALREADY_EXIST
                    });
                }
            }

            if (!string.IsNullOrEmpty(message.CustomerNumber))
            {
                application.CustomerNumber = message.CustomerNumber;
            }
            else
            {
                application.CustomerNumber   = "";
                application.CustomerName     = message.GivenName + " " + message.Surname;
                application.CountryCode      = message.CountryCode;
                application.PrefferedCulture = message.PrefferedCulture;
            }

            int activeOffers = 0;

            try
            {
                activeOffers = await HandleParties(application, message);

                var  financialStatement = new IdentifiedCommand <UpdateFinancialStatementsCommand, bool>(new UpdateFinancialStatementsCommand(application), new Guid());
                bool commandResult      = await _mediator.Send(financialStatement);
            }
            catch (InvalidCastException e)
            {
                _logger.LogError(e, "An error occurred while handling parties for new application");
                throw e;
            }
            catch (Exception e)
            {
                _logger.LogError(e, "An error occurred while handling involved parties for new application");
                return(new IntialOnlineOfferCommandResult {
                    ApplicationNumber = "", Result = CommandResult.INVALID_CALCULATION
                });
            }
            if (!string.IsNullOrEmpty(application.ProductCode))
            {
                ArrangementRequest arrangementRequest;
                try
                {
                    var handlingResponse = await HandleArrangementRequests(application, message);

                    arrangementRequest = handlingResponse.MainRequest;
                    List <string> productsList = new List <string>();
                    foreach (var arr in application.ArrangementRequests)
                    {
                        if (!productsList.Contains(arr.ProductCode))
                        {
                            productsList.Add(arr.ProductCode);
                        }
                        if (!string.IsNullOrEmpty(arr.ProductSnapshot.RelatedProducts) && application.ProductCode == arr.ProductCode)
                        {
                            productsList.AddRange(arr.ProductSnapshot.RelatedProducts.Split(",").Where(x => !productsList.Contains(x)).ToList());
                        }
                        //if (arr.ProductSnapshot.BundledProducts != null)
                        //{
                        //    list.AddRange(arr.ProductSnapshot.BundledProducts.Where(b => b.ProductKind != ProductKinds.AbstractProduct).Select(b => b.ProductCode).
                        //        Where(x => !list.Contains(x)).ToList());
                        //}
                    }
                    application.AvailableProducts = productsList;
                }
                catch (InvalidCalculationException e)
                {
                    throw e;
                }
                catch (Exception e)
                {
                    _logger.LogError(e, "An error occurred while adding arrangement requests for new application");
                    return(new IntialOnlineOfferCommandResult {
                        ApplicationNumber = "", Result = CommandResult.INVALID_CALCULATION
                    });
                }
                if (string.IsNullOrEmpty(application.ProductName))
                {
                    application.ProductName = application.ArrangementRequests
                                              .Where(r => r.ProductCode == application.ProductCode)
                                              .Select(r => r.ProductName)
                                              .FirstOrDefault();
                }

                application.PreferencialPrice = _priceCalculator.HasPreferentialPrice(arrangementRequest.Conditions);
            }

            OfferApplication addedApplication = _applicationRepository.Add(application);

            try
            {
                await _applicationRepository.UnitOfWork.SaveEntitiesAsync();

                await _auditClient.WriteLogEntry(AuditLogEntryAction.Apply, AuditLogEntryStatus.Success, "application", application.ApplicationNumber, "Applied for product", new { });
            }
            catch (Exception e)
            {
                _logger.LogError(e, "An error occurred while saving application");
                await _auditClient.WriteLogEntry(AuditLogEntryAction.Apply, AuditLogEntryStatus.Error, "application", application.ApplicationNumber, "An error occurred while applying for product");

                return(new IntialOnlineOfferCommandResult {
                    ApplicationNumber = "", Result = CommandResult.INVALID_CALCULATION
                });
            }
            // await HandleApplicationDocuments(application, message);
            await _applicationRepository.UnitOfWork.SaveEntitiesAsync();

            /////////////////////////////////////////////
            Console.WriteLine("Offer - IntialOnlineOfferCommandResult - CreateContentFolders start !!!");
            var dateBeforeCallStart = DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ss.fff",
                                                               CultureInfo.InvariantCulture);

            var createFolders = await _configurationService.GetEffective("offer/create-content-folders-automatically", "true");

            if (createFolders.Equals("true"))
            {
                Console.WriteLine("START CreateContentFolders {0}", dateBeforeCallStart);

                await CreateContentFolders(application);

                var dateAfterCallEnd = DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ss.fff",
                                                                CultureInfo.InvariantCulture);;
                Console.WriteLine("END CreateContentFolders: {0} ", dateAfterCallEnd);

                double milDiffCreateContentFolders = DateTime.Parse(dateAfterCallEnd).Subtract(DateTime.Parse(dateBeforeCallStart)).TotalMilliseconds;
                Console.WriteLine("Offer - CreateContentFolders - COUNT: {0} !!!", milDiffCreateContentFolders);
            }
            ///////////////////////////////////////
            application.Documents = application.Documents ?? new List <ApplicationDocument>();


            application = await _documentsResolver.ResolveDocuments(application);

            await _applicationRepository.UnitOfWork.SaveEntitiesAsync();

            //////////////////////
            ///
            if (createFolders.Equals("true"))
            {
                Console.WriteLine("Offer - IntialOnlineOfferCommandResult - CreateContentFolders start !!!");
                var dateBeforeCallDocumentsFolders = DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ss.fff",
                                                                              CultureInfo.InvariantCulture);
                Console.WriteLine("START CreateApplicationDocumentsFolders {0}", dateBeforeCallDocumentsFolders);



                await _documentsResolver.CreateApplicationDocumentsFolders();

                var dateAfterDocumentsFoldersEnd = DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ss.fff",
                                                                            CultureInfo.InvariantCulture);;
                Console.WriteLine("END CreateApplicationDocumentsFolders: {0} ", dateAfterDocumentsFoldersEnd);

                double milDiffCreateDocumentsFolders = DateTime.Parse(dateAfterDocumentsFoldersEnd).Subtract(DateTime.Parse(dateBeforeCallDocumentsFolders)).TotalMilliseconds;
                Console.WriteLine("Offer - CreateContentFolders - COUNT: {0} !!!", milDiffCreateDocumentsFolders);
                ///////////////////////////////////////
            }
            var messageObj = _messageEventFactory.CreateBuilder("offer", "offer-initiated");

            messageObj = messageObj.AddBodyProperty("initiator", message.Username)
                         .AddBodyProperty("channel", application.ChannelCode)
                         .AddBodyProperty("product-code", application.ProductCode)
                         .AddBodyProperty("product-name", application.ProductName)
                         .AddBodyProperty("email", message.EmailAddress)
                         .AddBodyProperty("mobile-phone", message.MobilePhone)
                         .AddBodyProperty("active-offers", activeOffers)
                         .AddBodyProperty("preferential-price", application.PreferencialPrice)
                         .AddBodyProperty("term-limit-breached", application.TermLimitBreached)
                         .AddBodyProperty("amount-limit-breached", application.AmountLimitBreached)
                         .AddBodyProperty("originates-bundle", application.OriginatesBundle)
                         .AddBodyProperty("party-id", application.InvolvedParties.Where(x => x.PartyRole == PartyRole.Customer).FirstOrDefault()?.PartyId)
                         .AddBodyProperty("is-proposal", message.IsProposal);
            if (application.LeadId != null)
            {
                var stat = Enum.GetName(typeof(ApplicationStatus), application.Status);
                messageObj.AddBodyProperty("lead-id", application.LeadId)
                .AddBodyProperty("status", stat)
                .AddBodyProperty("initiation-point", "targeted-by-campaign");
            }
            else if (message.IsProposal)
            {
                messageObj.AddBodyProperty("initiation-point", "proposal-initiated");
            }
            else
            {
                messageObj.AddBodyProperty("initiation-point", "applied");
            }
            var customerSegment = application.InvolvedParties.Where(x => x.PartyRole == PartyRole.Customer).FirstOrDefault()?.CustomerSegment;

            if (customerSegment == null)
            {
                customerSegment = await _configurationService.GetEffective("party/default-segment/individual", "professional");
            }
            if (!string.IsNullOrEmpty(message.CustomerNumber))
            {
                messageObj = messageObj.AddBodyProperty("customer-number", application.CustomerNumber)
                             .AddBodyProperty("customer-segment", customerSegment);
            }
            else
            {
                messageObj = messageObj.AddBodyProperty("customer-name", application.CustomerName)
                             .AddBodyProperty("given-name", message.GivenName)
                             .AddBodyProperty("family-name", message.Surname)
                             .AddBodyProperty("personal-identification-number", message.IdentificationNumber)
                             .AddBodyProperty("country-code", message.CountryCode)
                             .AddBodyProperty("customer-segment", customerSegment);
            }
            messageObj = messageObj.AddHeaderProperty("application-number", addedApplication.ApplicationNumber);
            // _logger.LogInformation("Sending offer initiated event to broker on topic {BrokerTopicName} for application: {ApplicationNumber}", "offer", addedApplication.ApplicationNumber);
            _eventBus.Publish(messageObj.Build());
            //////////////////
            var dateAfterCall = DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ss.fff",
                                                         CultureInfo.InvariantCulture);;

            Console.WriteLine("Offer - IntialOnlineOfferCommandResult - Handle END {0} ", dateAfterCall);
            double milDiff = DateTime.Parse(dateAfterCall).Subtract(DateTime.Parse(dateBeforeCall)).TotalMilliseconds;

            Console.WriteLine("Offer - IntialOnlineOfferCommandResult - Handle - COUNT: {0}", milDiff);
            /////////////
            ///
            return(new IntialOnlineOfferCommandResult()
            {
                ApplicationNumber = addedApplication.ApplicationNumber, Result = CommandResult.OK
            });
        }
Exemplo n.º 18
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);
        }
Exemplo n.º 19
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);
        }