using FinlyticAssets.Database; using FinlyticAssets.Entities; using Microsoft.EntityFrameworkCore; namespace FinlyticAssets.Services; /// /// Defines the business logic for managing global application settings. /// Supports retrieving and updating (upserting) the central single-row configuration record. /// public interface ISettingsDbService { /// /// Retrieves the current global settings from the database. /// /// /// A task that represents the asynchronous operation. The task result contains the current . /// If no settings exist in the database yet, a new instance initialized with default values is returned. /// public Task GetSettings(); /// /// Persists the provided settings by updating the existing record or inserting the first one if the table is empty. /// /// The new configuration values to be persisted. /// /// A task that represents the asynchronous operation. The task result contains the freshly saved /// and tracked instance. /// public Task SaveSettings(Settings settings); /// /// Updates settings from a key-value dictionary received via Admin Panel MQTT events. /// public Task UpdateSettingsFromDictionary(Dictionary dictionary); } /// /// Implements the utilizing Entity Framework Core. /// This service is designed for a single-row table architecture to maintain stateful global configurations. /// public class SettingsDbService : ISettingsDbService { private readonly AssetsDbContext _context; /// /// Initializes a new instance of the class with the required database context. /// /// The EF Core context used to access the assets database. public SettingsDbService(AssetsDbContext context) { _context = context; } /// Inherits documentation from interface. public async Task GetSettings() { var settings = await _context.Settings.AsNoTracking().FirstOrDefaultAsync(); if (settings == null) { settings = new Settings { Id = Guid.NewGuid() }; _context.Settings.Add(settings); await _context.SaveChangesAsync(); _context.ChangeTracker.Clear(); } return settings; } /// Inherits documentation from interface. public async Task SaveSettings(Settings settings) { var existing = await _context.Settings.FirstOrDefaultAsync(); if (existing == null) { if (settings.Id == Guid.Empty) { settings.Id = Guid.NewGuid(); } _context.Settings.Add(settings); await _context.SaveChangesAsync(); return settings; } else { existing.FinishedInitialScan = settings.FinishedInitialScan; existing.TradeRepublicMaxRequestPageSize = settings.TradeRepublicMaxRequestPageSize; existing.AssetUpdateTypeDelay = settings.AssetUpdateTypeDelay; existing.InitAssetUpdateTypeDelay = settings.InitAssetUpdateTypeDelay; existing.InitBatchAssetUpdateDelay = settings.InitBatchAssetUpdateDelay; existing.BatchAssetUpdateDelay = settings.BatchAssetUpdateDelay; existing.CurrentScanningType = settings.CurrentScanningType; existing.CurrentScanningPage = settings.CurrentScanningPage; _context.Settings.Update(existing); await _context.SaveChangesAsync(); return existing; } } /// Inherits documentation from interface. public async Task UpdateSettingsFromDictionary(Dictionary dictionary) { var settings = await GetSettings(); foreach (var (key, value) in dictionary) { if (string.Equals(key, "TradeRepublicMaxRequestPageSize", StringComparison.OrdinalIgnoreCase) && int.TryParse(value, out var ps)) settings.TradeRepublicMaxRequestPageSize = ps; else if (string.Equals(key, "AssetUpdateTypeDelay", StringComparison.OrdinalIgnoreCase) && int.TryParse(value, out var autd)) settings.AssetUpdateTypeDelay = autd; else if (string.Equals(key, "InitAssetUpdateTypeDelay", StringComparison.OrdinalIgnoreCase) && int.TryParse(value, out var iautd)) settings.InitAssetUpdateTypeDelay = iautd; else if (string.Equals(key, "BatchAssetUpdateDelay", StringComparison.OrdinalIgnoreCase) && int.TryParse(value, out var baud)) settings.BatchAssetUpdateDelay = baud; else if (string.Equals(key, "InitBatchAssetUpdateDelay", StringComparison.OrdinalIgnoreCase) && int.TryParse(value, out var ibaud)) settings.InitBatchAssetUpdateDelay = ibaud; else if (string.Equals(key, "FinishedInitialScan", StringComparison.OrdinalIgnoreCase) && bool.TryParse(value, out var fis)) settings.FinishedInitialScan = fis; } await SaveSettings(settings); } }