using System; using System.Linq; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Media.Imaging; using Comal.Classes; using InABox.Clients; using InABox.Configuration; using InABox.Core; using InABox.DynamicGrid; using InABox.Wpf; using InABox.WPF; using OpenExchangeRates; using Exception = System.Exception; namespace PRSDesktop; public class ForeignCurrencyGridSettings : BaseObject, IGlobalConfigurationSettings { [TextBoxEditor] [EditorSequence(1)] public string ApiKey { get; set; } = ""; [TextBoxEditor] [EditorSequence(2)] public string BaseCurrency { get; set; } = "AUD"; [IntegerEditor] [EditorSequence(3)] public int Digits { get; set; } = 4; } public class ForeignCurrencyGridPreferences : BaseObject, IUserConfigurationSettings { public DynamicGridSelectedFilterSettings Filters { get; set; } = new(); } public class ForeignCurrencyGrid : DynamicDataGrid { private readonly BitmapImage tick = PRSDesktop.Resources.tick.AsBitmapImage(); private readonly Button update; private ForeignCurrencyGridSettings _settings; private ForeignCurrencyGridPreferences _preferences; public ForeignCurrencyGrid() { Task[] tasks = { Task.Run(() => { _settings = new GlobalConfiguration().Load(); }), Task.Run(() => { _preferences = new UserConfiguration().Load(); }), }; Task.WaitAll(tasks); FilterComponent.SetSettings(_preferences!.Filters, false); FilterComponent.OnFiltersSelected += FilterComponent_OnFilterSelected; HiddenColumns.Add(x=>x.Code); HiddenColumns.Add(x=>x.Description); HiddenColumns.Add(x=>x.Identifier); HiddenColumns.Add(x=>x.Active); ActionColumns.Add(new DynamicTickColumn(x=>x.Active, tick, tick, null, ToggleActive)); AddButton(null, PRSDesktop.Resources.autoupdate.AsBitmapImage(), UpdateSettings); update = AddButton("Update", PRSDesktop.Resources.payment.AsBitmapImage(), UpdateExchangeRates); update.Visibility = !string.IsNullOrEmpty(_settings!.ApiKey) ? Visibility.Visible : Visibility.Collapsed; } private void FilterComponent_OnFilterSelected(DynamicGridSelectedFilterSettings settings) { _preferences.Filters = settings; new UserConfiguration().Save(_preferences); } private bool UpdateSettings(Button button, CoreRow[] rows) { if (DynamicGridUtils.EditObject(_settings)) { new GlobalConfiguration().Save(_settings); update.Visibility = !string.IsNullOrEmpty(_settings.ApiKey) ? Visibility.Visible : Visibility.Collapsed; } return false; } private bool ToggleActive(CoreRow? row) { if (row == null) return false; var fc = row.ToObject(); fc.Active = !fc.Active; new Client().Save(fc, $"Set to {(fc.Active ? "Active" : "InActive")} "); return true; } protected override BaseEditor? GetEditor(object item, DynamicGridColumn column) { BaseEditor? editor; if (column.ColumnName.Equals(nameof(ForeignCurrency.Identifier)) && string.IsNullOrWhiteSpace(_settings.ApiKey)) { editor = base.GetEditor(item, column)?.CloneEditor() ?? new NullEditor(); editor.Editable = Editable.Hidden; editor.Visible = Visible.Hidden; } else if (column.ColumnName.Equals(nameof(ForeignCurrency.ExchangeRate))) { var dblEditor = (base.GetEditor(item, column)?.CloneEditor() as DoubleEditor) ?? new DoubleEditor(); dblEditor.Digits = _settings.Digits; editor = dblEditor; } else editor = base.GetEditor(item, column); return editor; } private bool UpdateExchangeRates(Button button, CoreRow[] rows) { try { Progress.ShowModal("Retrieving Currencies", progress => { var data = new Client().Query().ToObjects().ToList(); progress.Report("Updating Data"); using (var client = new OpenExchangeRatesClient("ff16587e173b43788a34c035a2c53edd")) { var currencies = client.GetCurrenciesAsync().Result; if (currencies == null) throw new Exception("No Currencies Returned"); var rates = client.GetLatestRatesAsync().Result; if (rates == null) throw new Exception("No Rates Returned"); if (!rates.Rates.TryGetValue("AUD", out decimal aud_decimal)) throw new Exception("Cannot Find AUD rate"); var usd_aud = Convert.ToDouble(aud_decimal); if (usd_aud.IsEffectivelyEqual(0.0)) throw new Exception("USD -> AUD conversion return 0.00"); foreach (var rate in rates.Rates) { var foreign_usd = Convert.ToDouble(rate.Value); var items = data.Where(x => String.Equals(x.Identifier, rate.Key)).ToList(); if (!items.Any()) { if (currencies.TryGetValue(rate.Key, out string? description)) { var newitem = new ForeignCurrency() { Code = rate.Key, Description = description, Identifier = rate.Key, Active = false }; items.Add(newitem); data.Add(newitem); } } foreach (var item in items) item.ExchangeRate = foreign_usd / usd_aud; } } foreach (var currency in data.Where(x => !String.IsNullOrWhiteSpace(x.Identifier) && String.IsNullOrWhiteSpace(x.Symbol))) { currency.Symbol = currency.Identifier; } var updates = data.Where(x => x.IsChanged()).ToArray(); if (updates.Any()) { progress.Report($"Updating {updates.Length} records..."); new Client().Save(updates, "Updated from openexchangerates.org"); } }); } catch (Exception e) { MessageWindow.ShowError("Error retrieving data!", e); } return true; } }