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.º 2
0
 private void PerformCalculation(OfferApplication application, ArrangementRequest request)
 {
     if (request is FinanceServiceArrangementRequest finR)
     {
         try
         {
             request = _calculatorProvider.Calculate(finR, application);
             //var conversionMethod = _configurationService.GetEffective("offer/fee-currency-conversion-method", "Buy to middle").Result;
             //finR.CalculateOffer(application, _priceCalculator, conversionMethod);
         }
         catch (MaxNumberOfIterationsException e)
         {
             _logger.LogError(e, "Maximanl number of iterations exceeded while calculating price");
             throw e;
         }
         catch (Exception exp)
         {
             _logger.LogError(exp, "An unknown error occured while performing offer calculation");
             throw new InvalidCalculationException();
         }
     }
 }
        public 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.º 4
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
            });
        }