ForeignCurrencyGrid.cs 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. using System;
  2. using System.Linq;
  3. using System.Threading.Tasks;
  4. using System.Windows;
  5. using System.Windows.Controls;
  6. using System.Windows.Media.Imaging;
  7. using Comal.Classes;
  8. using InABox.Clients;
  9. using InABox.Configuration;
  10. using InABox.Core;
  11. using InABox.DynamicGrid;
  12. using InABox.Wpf;
  13. using InABox.WPF;
  14. using OpenExchangeRates;
  15. using Exception = System.Exception;
  16. namespace PRSDesktop;
  17. public class ForeignCurrencyGridSettings : BaseObject, IGlobalConfigurationSettings
  18. {
  19. [TextBoxEditor]
  20. [EditorSequence(1)]
  21. public string ApiKey { get; set; } = "";
  22. [TextBoxEditor]
  23. [EditorSequence(2)]
  24. public string BaseCurrency { get; set; } = "AUD";
  25. [IntegerEditor]
  26. [EditorSequence(3)]
  27. public int Digits { get; set; } = 4;
  28. }
  29. public class ForeignCurrencyGridPreferences : BaseObject, IUserConfigurationSettings
  30. {
  31. public DynamicGridSelectedFilterSettings Filters { get; set; } = new();
  32. }
  33. public class ForeignCurrencyGrid : DynamicDataGrid<ForeignCurrency>
  34. {
  35. private readonly BitmapImage tick = PRSDesktop.Resources.tick.AsBitmapImage();
  36. private readonly Button update;
  37. private ForeignCurrencyGridSettings _settings;
  38. private ForeignCurrencyGridPreferences _preferences;
  39. public ForeignCurrencyGrid()
  40. {
  41. Task[] tasks = {
  42. Task.Run(() =>
  43. {
  44. _settings = new GlobalConfiguration<ForeignCurrencyGridSettings>().Load();
  45. }),
  46. Task.Run(() =>
  47. {
  48. _preferences = new UserConfiguration<ForeignCurrencyGridPreferences>().Load();
  49. }),
  50. };
  51. Task.WaitAll(tasks);
  52. FilterComponent.SetSettings(_preferences!.Filters, false);
  53. FilterComponent.OnFiltersSelected += FilterComponent_OnFilterSelected;
  54. HiddenColumns.Add(x=>x.Code);
  55. HiddenColumns.Add(x=>x.Description);
  56. HiddenColumns.Add(x=>x.Identifier);
  57. HiddenColumns.Add(x=>x.Active);
  58. ActionColumns.Add(new DynamicTickColumn<ForeignCurrency,bool>(x=>x.Active, tick, tick, null, ToggleActive));
  59. AddButton(null, PRSDesktop.Resources.autoupdate.AsBitmapImage(), UpdateSettings);
  60. update = AddButton("Update", PRSDesktop.Resources.payment.AsBitmapImage(), UpdateExchangeRates);
  61. update.Visibility = !string.IsNullOrEmpty(_settings!.ApiKey) ? Visibility.Visible : Visibility.Collapsed;
  62. }
  63. private void FilterComponent_OnFilterSelected(DynamicGridSelectedFilterSettings settings)
  64. {
  65. _preferences.Filters = settings;
  66. new UserConfiguration<ForeignCurrencyGridPreferences>().Save(_preferences);
  67. }
  68. private bool UpdateSettings(Button button, CoreRow[] rows)
  69. {
  70. if (DynamicGridUtils.EditObject(_settings))
  71. {
  72. new GlobalConfiguration<ForeignCurrencyGridSettings>().Save(_settings);
  73. update.Visibility = !string.IsNullOrEmpty(_settings.ApiKey) ? Visibility.Visible : Visibility.Collapsed;
  74. }
  75. return false;
  76. }
  77. private bool ToggleActive(CoreRow? row)
  78. {
  79. if (row == null)
  80. return false;
  81. var fc = row.ToObject<ForeignCurrency>();
  82. fc.Active = !fc.Active;
  83. new Client<ForeignCurrency>().Save(fc, $"Set to {(fc.Active ? "Active" : "InActive")} ");
  84. return true;
  85. }
  86. protected override BaseEditor? GetEditor(object item, DynamicGridColumn column)
  87. {
  88. BaseEditor? editor;
  89. if (column.ColumnName.Equals(nameof(ForeignCurrency.Identifier)) && string.IsNullOrWhiteSpace(_settings.ApiKey))
  90. {
  91. editor = base.GetEditor(item, column)?.CloneEditor() ?? new NullEditor();
  92. editor.Editable = Editable.Hidden;
  93. editor.Visible = Visible.Hidden;
  94. }
  95. else if (column.ColumnName.Equals(nameof(ForeignCurrency.ExchangeRate)))
  96. {
  97. var dblEditor = (base.GetEditor(item, column)?.CloneEditor() as DoubleEditor) ?? new DoubleEditor();
  98. dblEditor.Digits = _settings.Digits;
  99. editor = dblEditor;
  100. }
  101. else
  102. editor = base.GetEditor(item, column);
  103. return editor;
  104. }
  105. private bool UpdateExchangeRates(Button button, CoreRow[] rows)
  106. {
  107. try
  108. {
  109. Progress.ShowModal("Retrieving Currencies", progress =>
  110. {
  111. var data = new Client<ForeignCurrency>().Query().ToObjects<ForeignCurrency>().ToList();
  112. progress.Report("Updating Data");
  113. using (var client = new OpenExchangeRatesClient("ff16587e173b43788a34c035a2c53edd"))
  114. {
  115. var currencies = client.GetCurrenciesAsync().Result;
  116. if (currencies == null)
  117. throw new Exception("No Currencies Returned");
  118. var rates = client.GetLatestRatesAsync().Result;
  119. if (rates == null)
  120. throw new Exception("No Rates Returned");
  121. if (!rates.Rates.TryGetValue("AUD", out decimal aud_decimal))
  122. throw new Exception("Cannot Find AUD rate");
  123. var usd_aud = Convert.ToDouble(aud_decimal);
  124. if (usd_aud.IsEffectivelyEqual(0.0))
  125. throw new Exception("USD -> AUD conversion return 0.00");
  126. foreach (var rate in rates.Rates)
  127. {
  128. var foreign_usd = Convert.ToDouble(rate.Value);
  129. var items = data.Where(x => String.Equals(x.Identifier, rate.Key)).ToList();
  130. if (!items.Any())
  131. {
  132. if (currencies.TryGetValue(rate.Key, out string? description))
  133. {
  134. var newitem = new ForeignCurrency()
  135. {
  136. Code = rate.Key,
  137. Description = description,
  138. Identifier = rate.Key,
  139. Active = false
  140. };
  141. items.Add(newitem);
  142. data.Add(newitem);
  143. }
  144. }
  145. foreach (var item in items)
  146. item.ExchangeRate = foreign_usd / usd_aud;
  147. }
  148. }
  149. foreach (var currency in data.Where(x =>
  150. !String.IsNullOrWhiteSpace(x.Identifier)
  151. && String.IsNullOrWhiteSpace(x.Symbol)))
  152. {
  153. currency.Symbol = currency.Identifier;
  154. }
  155. var updates = data.Where(x => x.IsChanged()).ToArray();
  156. if (updates.Any())
  157. {
  158. progress.Report($"Updating {updates.Length} records...");
  159. new Client<ForeignCurrency>().Save(updates, "Updated from openexchangerates.org");
  160. }
  161. });
  162. }
  163. catch (Exception e)
  164. {
  165. MessageWindow.ShowError("Error retrieving data!", e);
  166. }
  167. return true;
  168. }
  169. }