public async Task <CurrencyQuoteModel> LoadRateAsync()
        {
            DateTime rateDate = DateTime.Now;

            Log.Information("Loading BRL rates for {rateDate}", rateDate);
            Log.Information("Getting USD rate for {rateDate} to derivate BRL", rateDate);

            CurrencyQuoteModel usdRate = await RatesService.GetRateQuoteAsync("USD", rateDate);

            Log.Information("Retrieved USD rate: {usdRate}", usdRate);

            CurrencyQuoteModel brlRate = new CurrencyQuoteModel()
            {
                CurrencyCode  = "BRL",
                BuyValue      = usdRate.BuyValue / 4,
                SellValue     = usdRate.SellValue / 4,
                EffectiveDate = rateDate
            };

            Log.Information("Derivated BRL rate: {brlRate}", brlRate);

            await RatesService.AddRateAsync(brlRate);

            return(brlRate);
        }
        private async Task <List <CurrencyQuoteModel> > GetRatesAsync(string currencyCode = null, DateTime?date = null, bool?onlyLatest = false)
        {
            List <CurrencyQuoteModel> currencyQuotes = new List <CurrencyQuoteModel>();

            Log.Information($"Searching for '{currencyCode}' rates for '{date}'");

            List <Rate> rates = await RatesRepository.GetRatesAsync(currencyCode, date);

            Log.Information($"Found '{rates.Count}' rates");

            foreach (Rate rate in rates)
            {
                bool skipCurrentRecord = onlyLatest.HasValue && onlyLatest.Value && currencyQuotes.Any(q => q.CurrencyCode == rate.CurrencyCode);
                if (!skipCurrentRecord)
                {
                    CurrencyQuoteModel currencyQuote = new CurrencyQuoteModel()
                    {
                        RateId        = rate.Id,
                        CurrencyCode  = rate.CurrencyCode,
                        EffectiveDate = rate.EffectiveDate,
                        BuyValue      = rate.BuyValue,
                        SellValue     = rate.SellValue
                    };

                    currencyQuotes.Add(currencyQuote);
                }
            }

            return(currencyQuotes);
        }
        public async Task <CurrencyQuoteModel> GetRateQuoteAsync(string currencyCode, DateTime date)
        {
            Log.Information($"Searching for {currencyCode} rate for {date}");

            Rate rate = (await RatesRepository.GetRatesAsync(currencyCode, date))
                        .FirstOrDefault();

            if (rate != null)
            {
                Log.Information($"Found rate");

                CurrencyQuoteModel currencyQuote = new CurrencyQuoteModel()
                {
                    RateId        = rate.Id,
                    CurrencyCode  = rate.CurrencyCode,
                    EffectiveDate = rate.EffectiveDate,
                    BuyValue      = rate.BuyValue,
                    SellValue     = rate.SellValue
                };

                return(currencyQuote);
            }
            else
            {
                Log.Information($"No rate found");
            }

            return(null);
        }
        public async Task <bool> AddRateAsync(CurrencyQuoteModel currencyQuote)
        {
            Rate rate = new Rate()
            {
                CurrencyCode  = currencyQuote.CurrencyCode,
                EffectiveDate = currencyQuote.EffectiveDate,
                BuyValue      = currencyQuote.BuyValue,
                SellValue     = currencyQuote.SellValue,
                CreateDate    = DateTime.Now
            };

            RatesRepository.AddRate(rate);

            return((await RatesRepository.SaveChangesAsync()) > 0);
        }
        public async Task <IActionResult> ExecuteCurrencyExchangeAsync(CurrencyExchangeModel currencyExchangeModel)
        {
            if (!await RatesService.IsValidCurrencyToQuoteAsync(currencyExchangeModel.ForeignCurrencyCode))
            {
                return(BadRequest("Foreign currency not valid"));
            }

            if (currencyExchangeModel.Direction == CurrencyExchangeDirection.SellForeign)
            {
                return(BadRequest("Selling foreign currency not fully implemented yet (missing limit business logic)."));
            }

            DateTime           transactionDate     = DateTime.Now;
            CurrencyQuoteModel foreignCurrencyRate = await RatesService.GetRateQuoteAsync(currencyExchangeModel.ForeignCurrencyCode,
                                                                                          transactionDate);

            if (foreignCurrencyRate == null)
            {
                return(BadRequest($"No rate found for {currencyExchangeModel.ForeignCurrencyCode} on {transactionDate}"));
            }

            double foreignCurrencyAmount = CurrencyExchangeService.CalculateForeignCurrencyAmount(currencyExchangeModel.Direction,
                                                                                                  currencyExchangeModel.LocalCurrencyAmount,
                                                                                                  foreignCurrencyRate.SellValue,
                                                                                                  foreignCurrencyRate.BuyValue);

            double userRemainingLimit = await CurrencyExchangeService.GetUserRemainingLimitAsync(currencyExchangeModel.UserId,
                                                                                                 currencyExchangeModel.ForeignCurrencyCode,
                                                                                                 transactionDate);

            //TODO: This validation works corretly when buying foreign, but needs refactor for selling
            if (userRemainingLimit < foreignCurrencyAmount)
            {
                return(BadRequest("Operation would exceed monthly limits. Operation cancelled."));
            }

            CurrencyExchangeTransactionModel newTransaction = await CurrencyExchangeService.SubmitTransactionAsync(currencyExchangeModel,
                                                                                                                   foreignCurrencyAmount,
                                                                                                                   transactionDate,
                                                                                                                   foreignCurrencyRate.RateId);

            return(Ok(newTransaction));
        }
        public async Task <CurrencyQuoteModel> LoadRateAsync()
        {
            Log.Information("Starting to load USD rate");

            CurrencyQuoteModel usdRate = null;

            using (HttpClient httpClient = new HttpClient())
            {
                string url = $"https://www.bancoprovincia.com.ar/Principal/Dolar";

                Log.Information("Performing HTTP Request");

                using (HttpResponseMessage responseApi = await httpClient.GetAsync(url))
                {
                    Log.Information("Response received");

                    string response = await responseApi.Content.ReadAsStringAsync();

                    if (responseApi.IsSuccessStatusCode)
                    {
                        Log.Information("Response success, parsing to object. Raw string: {response}", response);

                        string[] responseObj = JsonConvert.DeserializeObject <string[]>(response);

                        usdRate = new CurrencyQuoteModel()
                        {
                            CurrencyCode  = "USD",
                            BuyValue      = Convert.ToDouble(responseObj[0], new CultureInfo("en-US")),
                            SellValue     = Convert.ToDouble(responseObj[1], new CultureInfo("en-US")),
                            EffectiveDate = DateTime.Now
                        };

                        Log.Information("Parsed rate: {usdRate}", usdRate);

                        await RatesService.AddRateAsync(usdRate);
                    }
                }
            }

            return(usdRate);
        }
Beispiel #7
0
        public async Task <IActionResult> GetAsync(string currencyCode, DateTime?date = null)
        {
            DateTime effectiveDate = DateTime.Now.Date;

            if (date.HasValue)
            {
                effectiveDate = date.Value.Date;
            }

            if (!await RatesService.IsValidCurrencyToQuoteAsync(currencyCode))
            {
                return(BadRequest("Currency not valid"));
            }

            CurrencyQuoteModel currencyQuote = await RatesService.GetRateQuoteAsync(currencyCode, effectiveDate);

            if (currencyQuote == null)
            {
                return(NotFound($"No quote found for {currencyCode} on {effectiveDate}"));
            }

            return(Ok(currencyQuote));
        }