示例#1
0
        public async Task <bool?> Handle(DeleteArrangementRequestCommand message, CancellationToken cancellationToken)
        {
            ArrangementRequest arrangementRequest;

            arrangementRequest = _arrangementRequestRepository.GetArrangementRequest(message.ApplicationNumber,
                                                                                     message.ArrangementRequestId, "product-snapshot", null);
            if (arrangementRequest == null)
            {
                return(null);
            }
            var requestsToDelete = _arrangementRequestRepository.GetBundledRequests(arrangementRequest, false);

            requestsToDelete.Add(arrangementRequest);
            var result = await _arrangementRequestRepository.DeleteArrangementRequests(message.ApplicationNumber, requestsToDelete);

            var application = await _applicationRepository.GetAsync(message.ApplicationNumber);

            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());

            await _auditClient.WriteLogEntry(AuditLogEntryAction.Delete, AuditLogEntryStatus.Success, "arrangement", message.ApplicationNumber.ToString(), "Arrangement deleted " + arrangementRequest.ArrangementRequestId, new { });

            return(result);
        }
        public async Task <bool?> Handle(UpdateApplicationDocumentsStatusCommand message, CancellationToken cancellationToken)
        {
            var documents = _applicationDocumentRepository.GetApplicationDocumentsForIds(message.DocumentIds);

            if (documents == null)
            {
                return(null);
            }
            documents.ForEach(d => d.Status = message.Status);
            _applicationDocumentRepository.UpdateApplicationDocuments(documents);
            try
            {
                foreach (var d in documents)
                {
                    var status           = d.Status;
                    var serializedStatus = JsonConvert.SerializeObject(status, new Newtonsoft.Json.Converters.StringEnumConverter());
                    var msgBuilder       =
                        _messageEventFactory.CreateBuilder("offer", "document-status-changed")
                        .AddHeaderProperty("application-number", message.ApplicationNumber)
                        .AddHeaderProperty("document-id", d.DocumentId)
                        .AddHeaderProperty("document-status", JsonConvert.DeserializeObject(serializedStatus).ToString())
                        .AddHeaderProperty("username", "ALL");

                    _bus.Publish(msgBuilder.Build());
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "UpdateApplicationDocumentsStatusCommandHandler error");
            }

            var saveResult = await _applicationDocumentRepository.UnitOfWork.SaveEntitiesAsync();

            return(saveResult);
        }
        public async Task <bool> Handle(DeleteSecuredDealLinkCommand message, CancellationToken cancellationToken)
        {
            var longApplicationNumber         = long.Parse(message.ApplicationNumber);
            CollateralRequirement requirement = _arrangementRequestRepository.GetCollateralRequirementById(longApplicationNumber, message.ArrangementRequestId, message.CollateralRequirementId);
            var result = false;

            try
            {
                var remainingDeals = requirement.SecuredDealLinks.Where
                                         (x => !x.ArrangementRequestId.Equals(message.ArrangementRequestId) ||
                                         !x.ApplicationNumber.Equals(message.ApplicationNumber) ||
                                         !x.ArrangementNumber.Equals(message.ArrangementNumber)).ToList();
                _logger.LogDebug("Number of remaining secure deal links is {SecureDealLinkCount}", remainingDeals.Count());
                requirement.SecuredDealLinks = remainingDeals;
                _arrangementRequestRepository.UpdateCollateralRequirement(requirement);
                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());
            }
            catch (Exception e)
            {
                _logger.LogError(e, "An error occurred while removing deal link from collateral requirement.");
            }
            return(result);
        }
示例#4
0
        public async Task <bool?> Handle(AddArrangementRequestCommand message, CancellationToken cancellationToken)
        {
            var request = message.ArrangementRequest;

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

            var application = await _applicationRepository.GetAsync(message.ApplicationNumber,
                                                                    "involved-parties,documents,arrangement-requests");

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

            if (string.IsNullOrEmpty(application.ProductCode))
            {
                application.ProductCode = request.ProductCode;
                application.ProductName = request.ProductName;
            }

            await _requestRepository.AddArrangementRequestsToApplication(application, new List <ArrangementRequest>() { request });

            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());
            return(true);
        }
示例#5
0
        public async Task <bool?> Handle(ProductKindsCommand message, CancellationToken cancellationToken)
        {
            var application = await _applicationRepository.GetAsync(message.ApplicationId);

            if (application != null)
            {
                CreditLineLimits cll = new CreditLineLimits
                {
                    ProductKinds = message.ProductKinds
                };
                var res = _arrangementRequestRepository.SetCreditLineProductKinds
                              (message.ApplicationId, message.ArrangementRequestId, cll, application);

                var appNumberString = "0000000000" + message.ApplicationId;
                appNumberString = appNumberString.Substring(appNumberString.Length - 10);
                _logger.LogDebug("Before publish ", appNumberString);
                var messageObj = _eventFactory.CreateBuilder("offer", "credit-line-limits-added")
                                 .AddBodyProperty("application-number", appNumberString)
                                 .AddHeaderProperty("application-number", appNumberString)
                                 .Build();
                _eventBus.Publish(messageObj);
                _logger.LogDebug("After publish ", appNumberString);
                return(await res);
            }
            return(null);
        }
示例#6
0
        public async Task <CommandStatus> Handle(CancelApplicationCommand message, CancellationToken cancellationToken)
        {
            var application = await this._applicationRepository.GetAsync(message.ApplicationNumber);

            if (application == null)
            {
                return(new CommandStatus {
                    CommandResult = StandardCommandResult.NOT_FOUND
                });
            }
            var statusInfo = new StatusInformation
            {
                Title       = "Canceled",
                Description = "Your request is cancelled.",
                Html        = ""
            };

            application.Status             = ApplicationStatus.Canceled;
            application.StatusInformation  = statusInfo;
            application.CancelationReason  = message.CancelationReason;
            application.CancelationComment = message.CancelationComment;
            _applicationRepository.Update(application);
            await _applicationRepository.UnitOfWork.SaveEntitiesAsync();

            try
            {
                await _auditClient.WriteLogEntry(AuditLogEntryAction.Cancel, AuditLogEntryStatus.Success, "application", application.ApplicationNumber, "Canceled application", new { });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Audit error in CancelApplicationCommandHandler");
            }

            var msgBuilder = _messageEventFactory.CreateBuilder("offer", "offer-canceled")
                             .AddHeaderProperty("application-number", message.ApplicationNumber.GetApplicationNumber())
                             .AddBodyProperty("cancelation-reason", application.CancelationReason);
            var commercialDetails = _applicationRepository.GetCommercialDetails(message.ApplicationNumber);

            if (application.LeadId != null)
            {
                var stat = Enum.GetName(typeof(ApplicationStatus), application.Status);
                msgBuilder.AddBodyProperty("status", stat)
                .AddBodyProperty("lead-id", application.LeadId);
            }
            if (commercialDetails != null)
            {
                foreach (var key in commercialDetails.Keys)
                {
                    msgBuilder.AddBodyProperty(key, commercialDetails[key]);
                }
            }
            _logger.LogInformation("Sending message {BrokerMessageName} event to broker on topic {BrokerTopicName} for application: {ApplicationNumber}", "offer-canceled", "offer", message.ApplicationNumber);
            _eventBus.Publish(msgBuilder.Build());
            return(new CommandStatus {
                CommandResult = StandardCommandResult.OK
            });
        }
示例#7
0
        public async Task <ArrangementRequest> SetAcceptedValues(long applicationNumber, int arrangementRequestId,
                                                                 AcceptedValues command, Application application)
        {
            var arrRequest = _context.ArrangementRequests.Include(ar => ar.ProductSnapshotDb).Where(p => p.ApplicationId == applicationNumber &&
                                                                                                    p.ArrangementRequestId == arrangementRequestId).FirstOrDefault();

            if (arrRequest == null)
            {
                throw new KeyNotFoundException("Requested arrangement does not exist for provided application.");
            }

            AcceptedValues acceptedValues = new AcceptedValues();

            if (arrRequest is TermLoanRequest tlr)
            {
                acceptedValues.Annuity = command.Annuity;
                tlr.Annuity            = command.Annuity;
                if (command.DownpaymentAmount != null)
                {
                    tlr.DownpaymentAmount     = command.DownpaymentAmount.Value;
                    tlr.DownpaymentPercentage = command.DownpaymentPercentage.Value;
                    tlr.InvoiceAmount         = command.InvoiceAmount.Value;
                }
            }
            if (arrRequest is FinanceServiceArrangementRequest fsa)
            {
                acceptedValues.Amount = command.Amount;
                acceptedValues.Term   = Utility.GetMonthsFromPeriod(command.Term).ToString();
                acceptedValues.Napr   = command.Napr;
                if (command.DownpaymentAmount != null)
                {
                    acceptedValues.DownpaymentAmount     = command.DownpaymentAmount.Value;
                    acceptedValues.DownpaymentPercentage = command.DownpaymentPercentage.Value;
                    acceptedValues.InvoiceAmount         = command.InvoiceAmount.Value;
                }
                fsa.Amount = command.Amount;
                fsa.Term   = Utility.GetMonthsFromPeriod(command.Term).ToString();
            }

            arrRequest.AcceptedValues = acceptedValues;

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

            arrRequest.CalculateOffer(application, _priceCalculator, conversionMethod);

            var res = await _context.SaveEntitiesAsync();

            var messageObj = _messageEventFactory.CreateBuilder("offer", "accepted-values-setted").Build();

            _bus.Publish(messageObj);

            return(arrRequest);
        }
        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);
            }
        }
示例#9
0
        public Task <string> Handle(InitiateGdprProcessCommand message, CancellationToken cancellationToken)
        {
            var caseId     = Guid.NewGuid().ToString();
            var msgBuilder = _messageEventFactory.CreateBuilder("offer", GetMessageNameForProcessKey(message.ProcessKey))
                             .AddBodyProperty("username", message.Username)
                             .AddBodyProperty("customer-number", message.CustomerNumber)
                             .AddBodyProperty("initiator", message.Initiator)
                             .AddBodyProperty("email", message.Email)
                             .AddBodyProperty("user-message", message.UserMessage)
                             .AddBodyProperty("case-id", caseId)
                             .AddHeaderProperty("case-id", caseId);

            _eventBus.Publish(msgBuilder.Build());

            return(null);
        }
示例#10
0
        public async Task <bool?> Handle(ArrangementRequestsAvailabilityCommand message, CancellationToken cancellationToken)
        {
            var application = await _applicationRepository.GetAsync(message.ApplicationId);

            if (application == null)
            {
                return(null);
            }
            var res        = _arrangementRequestRepository.UpdateArrangementRequestsAvailability(application, message.Availabilities);
            var messageObj = _eventFactory.CreateBuilder("offer", "arrangement-request-availability-changed")
                             .AddHeaderProperty("application-number", message.ApplicationNumber)
                             .Build();

            _eventBus.Publish(messageObj);
            return(await res);
        }
示例#11
0
        public async Task <bool> Handle(UpdateApplicationStatusCommand message, CancellationToken cancellationToken)
        {
            _logger.LogInformation("Updating application status to {applicationStatus} for application {applicationNumber}", message.Status, message.ApplicationId.GetApplicationNumber());
            var application    = _applicationRepository.UpdateStatus(message.ApplicationId, message.Status, message.StatusInformation, message.Phase);
            var messageBuilder = _messageEventFactory.CreateBuilder("offer", "status-updated")
                                 .AddHeaderProperty("application-number", message.ApplicationId.GetApplicationNumber())
                                 .AddHeaderProperty("username", application.Initiator.Contains("robot") ? "ALL" : application.Initiator);
            var commercialDetails = _applicationRepository.GetCommercialDetails(message.ApplicationId);

            if (message.Status != null && application.LeadId != null)
            {
                var stat = Enum.GetName(typeof(ApplicationStatus), application.Status);
                messageBuilder.AddBodyProperty("status", stat)
                .AddBodyProperty("lead-id", application.LeadId);
            }

            if (commercialDetails != null)
            {
                foreach (var key in commercialDetails.Keys)
                {
                    messageBuilder.AddBodyProperty(key, commercialDetails[key]);
                }
            }
            _logger.LogInformation("Sending offer status updated event to broker on topic {topicName} for application: {applicationNumber}", "offer", message.ApplicationId.GetApplicationNumber());
            var result = await _applicationRepository.UnitOfWork.SaveEntitiesAsync();

            try
            {
                await _auditClient.WriteLogEntry(AuditLogEntryAction.Update, AuditLogEntryStatus.Success, "application", application.ApplicationNumber, "Application status has been updated", new { });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Audit error in UpdateApplicationStatusCommandHandler");
            }

            _eventBus.Publish(messageBuilder.Build());
            return(result);
        }
示例#12
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
            });
        }
        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
            });
        }
示例#14
0
        public async Task <CommandStatus <Currency> > Handle(CalculateNewExposureCommand message, CancellationToken cancellationToken)
        {
            var application = await _applicationRepository.GetAsync(message.ApplicationNumber,
                                                                    "involved-parties,exposure-info,arrangement-requests");

            if (application == null)
            {
                _logger.LogError("Application {applicationNumber} not found for updating new exposure.", message.ApplicationNumber);
                new CommandStatus <Currency> {
                    CommandResult = StandardCommandResult.NOT_FOUND
                };
            }
            List <string> listOfCalcParties = new List <string>();
            var           customerNumber    = application.CustomerNumber;
            var           customer          = application.InvolvedParties.Find(p => p.CustomerNumber == application.CustomerNumber);

            var exposureInfo = new ExposureInfo();

            if (application.ExposureInfo != null)
            {
                exposureInfo = application.ExposureInfo;
            }
            // exposure in current application
            exposureInfo.NewExposureInCurrentApplication = new ExposureList
            {
                Exposures = new List <Exposure>()
            };

            await CalculateExposuresForApplication(application, exposureInfo.NewExposureInCurrentApplication);

            // Convert amounts to TargetCurrency
            var totalCategory = _applicationRepository.CalculateExposureInTargetCurrency(exposureInfo.NewExposureInCurrentApplication);

            // exposure in other applications on Offer
            exposureInfo.NewExposureInOtherApplications = new ExposureList
            {
                Exposures = new List <Exposure>()
            };
            var activeAppStatuses = _configurationService.GetEffective("offer/active-statuses", "draft,active,approved,accepted").Result;
            var activeRoles       = _configurationService.GetEffective("offer/exposure/active-roles", "customer,guarantor,co-debtor").Result;
            var statusesList      = EnumUtils.GetEnumPropertiesForListString <ApplicationStatus>(activeAppStatuses);
            var rolesList         = EnumUtils.GetEnumPropertiesForListString <PartyRole>(activeRoles);
            var otherApplications = new List <OfferApplication>();

            if (string.IsNullOrEmpty(customerNumber))
            {
                //prospect
                var email = ((IndividualParty)application.InvolvedParties.Where(x => x.PartyRole == PartyRole.Customer).FirstOrDefault()).EmailAddress;
                otherApplications = _applicationRepository.CheckExistingOffersForProspect(application.Initiator, email, statusesList, rolesList);
            }
            else
            {
                //existing customer
                await GetAppsForExposureRelatedGroups(customerNumber, customer, otherApplications, statusesList, rolesList, listOfCalcParties);
            }
            otherApplications = otherApplications
                                .Where(x => !x.ApplicationNumber.Equals(application.ApplicationNumber))
                                .ToList(); //exclude current application
            foreach (var app in otherApplications)
            {
                await CalculateExposuresForApplication(app, exposureInfo.NewExposureInOtherApplications);
            }

            // Exposure in other applications on other services
            try
            {
                var externalPotentialExposure = await GetExposureOnExternalApplications(application.CustomerNumber);

                exposureInfo.NewExposureInOtherApplications.Exposures.AddRange(externalPotentialExposure.Exposures);
                exposureInfo.NewExposureInOtherApplications.TotalApprovedAmountInTargetCurrency += externalPotentialExposure.TotalApprovedAmountInTargetCurrency;
            }
            catch (Exception e)
            {
                _logger.LogError(e, "An error occurred while calculating exposure in external sources");
            }

            // Convert amounts to TargetCurrency
            totalCategory = _applicationRepository.CalculateExposureInTargetCurrency(exposureInfo.NewExposureInOtherApplications);
            _applicationRepository.CalculateExposureInTargetCurrency(exposureInfo.CurrentExposure);
            _applicationRepository.CalculateExposureInTargetCurrency(exposureInfo.CreditBureauExposure);

            var targetCurrency = _configurationService.GetEffective("offer/exposure/target-currency", "EUR").Result;

            var totalCurrentExposure      = exposureInfo.CurrentExposure?.TotalApprovedAmountInTargetCurrency ?? 0;
            var totalCurrentAppExposure   = exposureInfo.NewExposureInCurrentApplication?.TotalApprovedAmountInTargetCurrency ?? 0;
            var totalOtherAppsExposure    = exposureInfo.NewExposureInOtherApplications?.TotalApprovedAmountInTargetCurrency ?? 0;
            var totalCreditBureauExposure = exposureInfo.CreditBureauExposure?.TotalApprovedAmountInTargetCurrency ?? 0;

            var totalCurrentDebtExposure      = exposureInfo.CurrentExposure?.TotalOutstandingAmountInTargetCurrency ?? 0;
            var totalCurrentDebtAppExposure   = exposureInfo.NewExposureInCurrentApplication?.TotalOutstandingAmountInTargetCurrency ?? 0;
            var totalOtherDebtAppsExposure    = exposureInfo.NewExposureInOtherApplications?.TotalOutstandingAmountInTargetCurrency ?? 0;
            var totalDebtCreditBureauExposure = exposureInfo.CreditBureauExposure?.TotalOutstandingAmountInTargetCurrency ?? 0;

            exposureInfo.TotalExposureApprovedAmount    = totalCurrentExposure + totalCurrentAppExposure + totalOtherAppsExposure;
            exposureInfo.TotalExposureOutstandingAmount = totalCurrentDebtExposure + totalCurrentAppExposure + totalOtherAppsExposure;

            exposureInfo.TotalCbApprovedExposureAmount = totalCreditBureauExposure + totalCurrentAppExposure + totalOtherAppsExposure;
            exposureInfo.TotalCbOutstandingAmount      = totalDebtCreditBureauExposure + totalCurrentAppExposure + totalOtherAppsExposure;

            exposureInfo.TotalExposureCurrency = targetCurrency;
            exposureInfo.CalculatedDate        = DateTime.UtcNow;
            await getCalculatedExposure(exposureInfo);

            application.ExposureInfo = exposureInfo;
            _applicationRepository.Update(application);
            var messageBuilder = _messageEventFactory.CreateBuilder("offer", "offer-exposure-calculated")
                                 .AddBodyProperty("product-code", application.ProductCode)
                                 .AddBodyProperty("product-name", application.ProductName)
                                 .AddBodyProperty("preferential-price", application.PreferencialPrice)
                                 .AddBodyProperty("term-limit-breached", application.TermLimitBreached)
                                 .AddBodyProperty("amount-limit-brached", application.AmountLimitBreached)
                                 .AddHeaderProperty("application-number", application.ApplicationNumber);

            _eventBus.Publish(messageBuilder.Build());
            Currency result   = null;
            bool     resultOk = await _applicationRepository.UnitOfWork.SaveEntitiesAsync();

            if (resultOk)
            {
                result = new Currency {
                    Amount = exposureInfo.TotalExposureApprovedAmount ?? 0, Code = exposureInfo.TotalExposureCurrency
                };
            }
            else
            {
                _logger.LogError("Updating new exposure data for application {applicationNumber} has failed.", message.ApplicationNumber);
                return(new CommandStatus <Currency> {
                    CommandResult = StandardCommandResult.INTERNAL_ERROR
                });
            }

            await _auditClient.WriteLogEntry(AuditLogEntryAction.Post, AuditLogEntryStatus.Success, "exposure-calculation", application.ApplicationNumber.ToString(), "Calculated new exposure", result);

            return(new CommandStatus <Currency> {
                CommandResult = StandardCommandResult.OK, Result = result
            });
        }