diff --git a/PcgsInvUi/App.axaml.cs b/PcgsInvUi/App.axaml.cs index 24ec2fd..5caf5d2 100644 --- a/PcgsInvUi/App.axaml.cs +++ b/PcgsInvUi/App.axaml.cs @@ -16,12 +16,8 @@ public partial class App : Application { public override void OnFrameworkInitializationCompleted() { base.OnFrameworkInitializationCompleted(); - // Create a connection to SQLite - var database = new Database(); - var coin = database.GetCoin(1003, "AG-3"); - if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) { - var coins = new Services.CoinCollection(); + var coins = new Database(); desktop.MainWindow = new MainWindow { DataContext = new MainWindowViewModel(coins), diff --git a/PcgsInvUi/Services/Database.cs b/PcgsInvUi/Services/Database.cs index 82bb139..ad28908 100644 --- a/PcgsInvUi/Services/Database.cs +++ b/PcgsInvUi/Services/Database.cs @@ -46,7 +46,7 @@ public class Database { SQLiteCommand cmd = Connection.CreateCommand(); cmd.CommandText = $"CREATE TABLE IF NOT EXISTS {collectionName} (" + - "PCGS_NUMBER INTEGER," + + "PCGS_NUMBER TEXT," + "GRADE TEXT" + "NAME TEXT," + "YEAR INTEGER," + @@ -60,7 +60,7 @@ public class Database { "SERIES_NAME TEXT," + "CATEGORY TEXT," + "DESIGNATION TEXT," + - "CERT_NUM TEXT," + + "CERT_NUM INTEGER," + "QUANTITY INTEGER," + "PRIMARY KEY(PCGS_NUMBER, GRADE))"; @@ -79,17 +79,15 @@ public class Database { // Create a SQL command. SQLiteCommand cmd = Connection.CreateCommand(); cmd.CommandText = - "INSERT INTO CollectionTable (PCGS_NUMBER, GRADE, NAME, YEAR," + + "INSERT INTO CollectionTable (PCGS_NUMBER, GRADE, YEAR," + "DENOMINATION, MINT_MARK, PRICE_GUIDE_VALUE, COIN_FACTS_LINK," + "MAJOR_VARIETY, MINOR_VARIETY, DIE_VARIETY, SERIES_NAME, CATEGORY, DESIGNATION," + "CERT_NUM, QUANTITY) " + - "VALUES (@PcgsNumber, @Name, @Grade, @Value, @Year, @Denomination, @MintMark, @PriceGuideValue," + + "VALUES (@PcgsNumber, @Grade, @Year, @Denomination, @MintMark, @PriceGuideValue," + "@CoinFactsLink, @MajorVariety, @MinorVariety, @DieVariety, @SeriesName, @Category, @Designation," + "@CertificateNumber, @Quantity)"; cmd.Parameters.AddWithValue("@PcgsNumber", newCoin.PCGSNo); - cmd.Parameters.AddWithValue("@Name", newCoin.Name); cmd.Parameters.AddWithValue("@Grade", newCoin.Grade); - cmd.Parameters.AddWithValue("@Value", newCoin.PriceGuideValue); cmd.Parameters.AddWithValue("@Year", newCoin.Year); cmd.Parameters.AddWithValue("@Denomination", newCoin.Denomination); cmd.Parameters.AddWithValue("@MintMark", newCoin.MintMark); @@ -117,34 +115,59 @@ public class Database { using (var reader = cmd.ExecuteReader()) { while (reader.Read()) { // Create coin from reader then add to list. - Coin coin = new Coin(); - coins.Add(coin); + coins.Add(CoinFromReader(reader)); } } return coins; } - public Coin GetCoin(int pcgsNumber, string grade) { + public Coin? GetCoin(int pcgsNumber, string grade) { // Get the coin based off of the pcgs number. SQLiteCommand cmd = Connection.CreateCommand(); cmd.CommandText = "SELECT * FROM CollectionTable WHERE Id = @Id AND Grade = @Grade"; cmd.Parameters.AddWithValue("@Id", pcgsNumber); cmd.Parameters.AddWithValue("@Grade", grade); + + Coin? returnCoin = null; // Execute the command. using (var reader = cmd.ExecuteReader()) { while (reader.Read()) { - // TODO Create a coin from the reader. - Console.WriteLine(reader.ToString()); - Coin coin = new Coin(); + returnCoin = CoinFromReader(reader); } } - return new Coin(); + return returnCoin; + } + + private Coin CoinFromReader(SQLiteDataReader reader) { + Coin coin = new Coin(); + coin.PCGSNo = reader.GetString(0); + coin.Grade = reader.GetString(1); + coin.Year = reader.GetInt32(2); + coin.Denomination = reader.GetString(3); + coin.MintMark = reader.GetString(4); + coin.PriceGuideValue = reader.GetDouble(5); + coin.CoinFactsLink = reader.GetString(6); + coin.MajorVariety = reader.GetString(7); + coin.MinorVariety = reader.GetString(8); + coin.DieVariety = reader.GetString(9); + coin.SeriesName = reader.GetString(10); + coin.Category = reader.GetString(11); + coin.Designation = reader.GetString(12); + coin.CertificateNumber = reader.GetInt32(13); + coin.Quantity = reader.GetInt32(14); + coin.TotalPrice = coin.Quantity * coin.PriceGuideValue; + return coin; } public void DeleteCoin(Coin delCoin) { + SQLiteCommand cmd = Connection.CreateCommand(); + cmd.CommandText = "DELETE FROM CollectionTable WHERE PCGS_NUMBER = @PcgsNumber AND GRADE = @Grade"; + cmd.Parameters.AddWithValue("@PcgsNumber", delCoin.PCGSNo); + cmd.Parameters.AddWithValue("@Grade", delCoin.Grade); + cmd.ExecuteNonQuery(); } } \ No newline at end of file diff --git a/PcgsInvUi/ViewModels/MainWindowViewModel.cs b/PcgsInvUi/ViewModels/MainWindowViewModel.cs index 121f328..6fd3ade 100644 --- a/PcgsInvUi/ViewModels/MainWindowViewModel.cs +++ b/PcgsInvUi/ViewModels/MainWindowViewModel.cs @@ -14,25 +14,26 @@ namespace PcgsInvUi.ViewModels; // TODO Error handling. // TODO Manual handling of API key. // TODO Use CoinFacts link. +// TODO Splash screen that loads. // TODO Take giant sheet of coins to integrate into the application. -// TODO Update all coins. +// TODO Update all coins. Choose those that are older first. // TODO API request tracker (1000 per day) -// TODO API update schedules (per month? manual override? needs to store a date of last update in the coin object) +// TODO Ok button greys out while request is happening. +// TODO Track when coins were last updated. +// TODO Image for coin in notes view. public class MainWindowViewModel : ViewModelBase { public ViewModelBase SidebarContent { get => _sideContent; private set => this.RaiseAndSetIfChanged(ref _sideContent, value); } - public ObservableCollection CoinCollection { get; set; } public ObservableCollection DisplayedList { get; set; } - + public Database ConnectedDatabase { get; set; } public Coin? SelectedCoin { get => _selectedCoin; set => this.RaiseAndSetIfChanged(ref _selectedCoin, value); } - public double TotalValue { get => _totalValue; set => this.RaiseAndSetIfChanged(ref _totalValue, value); @@ -48,10 +49,14 @@ public class MainWindowViewModel : ViewModelBase { private double _totalValue; private PcgsClient _pcgsClient; - public MainWindowViewModel(CoinCollection coins) { + // public MainWindowViewModel(CoinCollection coins) { + public MainWindowViewModel(Database coins) { + ConnectedDatabase = coins; var newViewModel = new NewViewModel(); _sideContent = newViewModel; - DisplayedList = CoinCollection = new ObservableCollection(coins.GetItems()); + // DisplayedList = CoinCollection = new ObservableCollection(coins.GetItems()); + DisplayedList = CoinCollection = + new ObservableCollection(coins.GetCollection("CollectionTable")); _pcgsClient = new PcgsClient( "eAb8gS0I2XAvT_5gJeiGJaglMia1Tk-oB4kJUK6kuafyrny_S61vIJY-Ikl4nCQM67wrdxzUqLVWTV2kBSxD3d5XNBHxHnYBhcSS6dOPug0hZaF3qAv56df3gYSzOGh9Tif5y0eP3Iw0LrqKDr1Hj-dk6SV6GKog2IIqCPQhhHH8FMTWBTYO-_O8cx7qLdM5GM8KlTsic6g3VRUhM8EA_4OO04dCfmNLGhqINRl3jGZ0Q4ziI8fng2bVWsIyteqiPzUn10rIQ3-OPpqVZG_DxeOmOejj4GzbUNyqUOajy-nr5rYY"); @@ -62,8 +67,10 @@ public class MainWindowViewModel : ViewModelBase { DeleteCommand = ReactiveCommand.CreateFromTask(async () => { var deleteViewModel = new DeleteWindowViewModel(); var result = await ShowDeleteWindow.Handle(deleteViewModel); - if (result) + if (result && SelectedCoin != null) { + ConnectedDatabase.DeleteCoin(SelectedCoin); CoinCollection.Remove(SelectedCoin); // possible null deref - ignored due to button being disabled. + } }, deleteEnabled); // Set up the ability to open the find window. @@ -85,6 +92,7 @@ public class MainWindowViewModel : ViewModelBase { var newCoin = await _pcgsClient.GetCoinFactsByGrade(requestStructure.Item1, requestStructure.Item2); newCoin.Quantity = requestStructure.Item3; CoinCollection.Add(newCoin); + coins.InsertCoin(newCoin); TotalValue += newCoin.Quantity * newCoin.PriceGuideValue; });