public async Task RunPriceListSynchronizationAsync() { var cancellationToken = CancellationToken.None; var statistics = new PriceListSynchronizationStatistics(); string priceListStatusMessage; try { var lastAppliedPriceListId = await _persistentCache.GetValueAsync(LastAppliedElitPriceListIdKey, cancellationToken); var priceList = await _elitUaClient.GetUnappliedPriceListAsync(lastAppliedPriceListId, cancellationToken); if (!priceList.IsSuccess) { throw new InvalidOperationException(priceList.StatusMessage); } priceListStatusMessage = priceList.StatusMessage; if (priceList.Records?.Count > 0) { await _ekSearchManagementClient.CreateProductIndexIfNotExistAsync(); using (var searchIndexClient = _ekSearchManagementClient.CreateSearchIndexClient()) { searchIndexClient.IndexName = _ekSearchManagementClient.ProductsIndexName; var updateUtcTimestamp = TimestampHelper.GetCurrentUtcTotalMinutes(); // max size of Azure Search batch const int PageSize = 1_000; var page = 0; foreach (var priceListPage in priceList.Records.Batch(PageSize)) { _logger.LogTrace(LoggingEvents.Synchronization, $"Processing {page*PageSize}+{PageSize}..."); await IndexPriceListPageAsync(searchIndexClient, priceListPage.ToArray(), updateUtcTimestamp, statistics); page++; } // wait half of minute until changes are applied await Task.Delay(TimeSpan.FromSeconds(30), cancellationToken); await PriceListHelper.CleanExpiredRecordsAsync( searchIndexClient, EkProductSourceEnum.ElitUa, updateUtcTimestamp, statistics, _logger); } } await _persistentCache.SetValueAsync(LastAppliedElitPriceListIdKey, priceList.PriceListId, CancellationToken.None); } catch (Exception ex) { _logger.LogError(LoggingEvents.UnhandledException, ex, "Elit price list synchronization failed."); await _notificationManager.SendWorkerMessageAsync($"ERROR! Elit price list synchronization failed, {statistics}: {ex.Message}"); throw; } await _notificationManager.SendWorkerMessageAsync($"Elit price list synchronization succeed, {statistics}, status: {priceListStatusMessage}"); }
public async Task AutoUpdateRatesAsync(CancellationToken cancellationToken) { try { // NBU string nbuRatesStatusMessage; var nbuRates = await _uaCentralBankApiProxy.GetRatesAsync(); if (nbuRates.Count > 0) { var lastAppliedNbuRatesDateString = await _persistentCache.GetValueAsync(LastAppliedNbuRatesDateKey, cancellationToken); // at the moment NBU returns rates only for one date var nbuRateDate = nbuRates[0].Date; var nbuRateDateString = nbuRateDate.ToString("yyyy-MM-dd"); if (lastAppliedNbuRatesDateString == nbuRateDateString) { nbuRatesStatusMessage = $"INFO: NBU rates are already updated to {nbuRateDateString}."; } else { // tomorrow 00:00 var uahRateUpdateStartTime = TimeZones.GetTimeZoneNow(TimeZones.UkrainianTime).Date.AddDays(1); var uahRates = await _dbContext.CentralBankExchangeRates .Where(x => x.LocalCurrencyCode == "UAH") .Select(x => new { x.Id, x.LocalCurrencyCode, x.ForeignCurrencyCode, }) .ToArrayAsync(cancellationToken); var updatedCurrencies = new List <string>(); foreach (var uahRate in uahRates) { var nbuRate = nbuRates .Where(x => x.LocalCurrencyCode == uahRate.LocalCurrencyCode && x.ForeignCurrencyCode == uahRate.ForeignCurrencyCode) .FirstOrDefault(); if (nbuRate != null) { _dbContext.CentralBankExchangeRateUpdates.Add( new CentralBankExchangeRateUpdate() { CentralBankExchangeRateId = uahRate.Id, Rate = nbuRate.Rate, StartTime = uahRateUpdateStartTime, }); updatedCurrencies.Add(nbuRate.ForeignCurrencyCode); } } await _dbContext.SaveChangesAsync(cancellationToken); await _persistentCache.SetValueAsync(LastAppliedNbuRatesDateKey, nbuRateDateString, CancellationToken.None); nbuRatesStatusMessage = $"SUCCESS: NBU rates for {string.Join(", ", updatedCurrencies)} were updated to {nbuRateDateString}."; } } else { nbuRatesStatusMessage = "WARNING: No NBU rates."; } await _notificationManager.SendWorkerMessageAsync(nbuRatesStatusMessage); } catch (Exception ex) { _logger.LogError(LoggingEvents.UnhandledException, ex, $"{nameof(AutoUpdateRatesAsync)} failed."); await _notificationManager.SendWorkerMessageAsync($"ERROR: {nameof(AutoUpdateRatesAsync)} failed: {ex.Message}."); } }