Merge vas-working to master (attempt 2) #2
No files matched your search
+10
-3
@@ -1,3 +1,5 @@
|
|||||||
|
using System;
|
||||||
|
using System.Data.Entity.Migrations.Model;
|
||||||
using Avalonia;
|
using Avalonia;
|
||||||
using Avalonia.Controls.ApplicationLifetimes;
|
using Avalonia.Controls.ApplicationLifetimes;
|
||||||
using Avalonia.Markup.Xaml;
|
using Avalonia.Markup.Xaml;
|
||||||
@@ -15,15 +17,20 @@ public partial class App : Application {
|
|||||||
|
|
||||||
public override void OnFrameworkInitializationCompleted() {
|
public override void OnFrameworkInitializationCompleted() {
|
||||||
base.OnFrameworkInitializationCompleted();
|
base.OnFrameworkInitializationCompleted();
|
||||||
|
|
||||||
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) {
|
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) {
|
||||||
var coins = new CoinDatabase();
|
var coins = new CoinDatabase();
|
||||||
|
|
||||||
desktop.MainWindow = new MainWindow {
|
desktop.MainWindow = new MainWindow {
|
||||||
DataContext = new MainWindowViewModel(coins),
|
DataContext = new MainWindowViewModel(coins),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
desktop.Exit += (sender, args) => {
|
||||||
|
coins.UpdateCollection("CollectionTable");
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
base.OnFrameworkInitializationCompleted();
|
base.OnFrameworkInitializationCompleted();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void OnExit(object sender, ControlledApplicationLifetimeExitEventArgs e) {
|
||||||
|
// Save the database?
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
using System;
|
using ReactiveUI;
|
||||||
using ReactiveUI;
|
|
||||||
|
|
||||||
namespace PcgsInvUi.Models;
|
namespace PcgsInvUi.Models;
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<OutputType>WinExe</OutputType>
|
<OutputType>WinExe</OutputType>
|
||||||
<TargetFramework>net6.0</TargetFramework>
|
<TargetFramework>net7.0</TargetFramework>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
<BuiltInComInteropSupport>true</BuiltInComInteropSupport>
|
<BuiltInComInteropSupport>true</BuiltInComInteropSupport>
|
||||||
<ApplicationManifest>app.manifest</ApplicationManifest>
|
<ApplicationManifest>app.manifest</ApplicationManifest>
|
||||||
@@ -15,13 +15,13 @@
|
|||||||
|
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Avalonia" Version="11.0.2"/>
|
<PackageReference Include="Avalonia" Version="11.0.5" />
|
||||||
<PackageReference Include="Avalonia.Desktop" Version="11.0.2"/>
|
<PackageReference Include="Avalonia.Desktop" Version="11.0.5" />
|
||||||
<PackageReference Include="Avalonia.Themes.Fluent" Version="11.0.2"/>
|
<PackageReference Include="Avalonia.Themes.Fluent" Version="11.0.5" />
|
||||||
<PackageReference Include="Avalonia.Fonts.Inter" Version="11.0.2"/>
|
<PackageReference Include="Avalonia.Fonts.Inter" Version="11.0.5" />
|
||||||
<!--Condition below is needed to remove Avalonia.Diagnostics package from build output in Release configuration.-->
|
<!--Condition below is needed to remove Avalonia.Diagnostics package from build output in Release configuration.-->
|
||||||
<PackageReference Condition="'$(Configuration)' == 'Debug'" Include="Avalonia.Diagnostics" Version="11.0.2"/>
|
<PackageReference Condition="'$(Configuration)' == 'Debug'" Include="Avalonia.Diagnostics" Version="11.0.5" />
|
||||||
<PackageReference Include="Avalonia.ReactiveUI" Version="11.0.2"/>
|
<PackageReference Include="Avalonia.ReactiveUI" Version="11.0.5" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3"/>
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.3"/>
|
||||||
<PackageReference Include="System.Data.SQLite" Version="1.0.118"/>
|
<PackageReference Include="System.Data.SQLite" Version="1.0.118"/>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
@@ -83,4 +83,9 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Remove="obj\**"/>
|
<None Remove="obj\**"/>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Reference Include="System.Data" />
|
||||||
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.ObjectModel;
|
||||||
using System.Data.SQLite;
|
using System.Data.SQLite;
|
||||||
using PcgsInvUi.Models;
|
using PcgsInvUi.Models;
|
||||||
|
|
||||||
@@ -8,13 +8,30 @@ namespace PcgsInvUi.Services;
|
|||||||
public class CoinDatabase {
|
public class CoinDatabase {
|
||||||
public SQLiteConnection Connection { get; set; }
|
public SQLiteConnection Connection { get; set; }
|
||||||
private Boolean IsConnected { get; set; }
|
private Boolean IsConnected { get; set; }
|
||||||
|
public ObservableCollection<Coin> Collection { get; set; }
|
||||||
|
|
||||||
|
private PcgsClient _pcgsClient;
|
||||||
|
|
||||||
public CoinDatabase() {
|
public CoinDatabase() {
|
||||||
// Create a connection to SQLite
|
// Create a connection to SQLite
|
||||||
Connection = CreateConnection();
|
Connection = CreateConnection();
|
||||||
|
// Create a client to access the API.
|
||||||
|
_pcgsClient = new PcgsClient(
|
||||||
|
"eAb8gS0I2XAvT_5gJeiGJaglMia1Tk-oB4kJUK6kuafyrny_S61vIJY-Ikl4nCQM67wrdxzUqLVWTV2kBSxD3d5XNBHxHnYBhcSS6dOPug0hZaF3qAv56df3gYSzOGh9Tif5y0eP3Iw0LrqKDr1Hj-dk6SV6GKog2IIqCPQhhHH8FMTWBTYO-_O8cx7qLdM5GM8KlTsic6g3VRUhM8EA_4OO04dCfmNLGhqINRl3jGZ0Q4ziI8fng2bVWsIyteqiPzUn10rIQ3-OPpqVZG_DxeOmOejj4GzbUNyqUOajy-nr5rYY");
|
||||||
// Create a base table.
|
// Create a base table.
|
||||||
CreateCollection("CollectionTable");
|
CreateCollection("CollectionTable");
|
||||||
Console.WriteLine("Connected to database.");
|
Console.WriteLine("Connected to database.");
|
||||||
|
Collection = new ObservableCollection<Coin>();
|
||||||
|
GetCollection("CollectionTable");
|
||||||
|
Console.WriteLine("Got collection.");
|
||||||
|
}
|
||||||
|
|
||||||
|
~CoinDatabase() {
|
||||||
|
Console.WriteLine("Destructor called, saving collection.");
|
||||||
|
// Save collection.
|
||||||
|
UpdateCollection("CollectionTable");
|
||||||
|
// Close the connection.
|
||||||
|
Connection.Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
private SQLiteConnection CreateConnection() {
|
private SQLiteConnection CreateConnection() {
|
||||||
@@ -62,13 +79,15 @@ public class CoinDatabase {
|
|||||||
"DESIGNATION TEXT," +
|
"DESIGNATION TEXT," +
|
||||||
"CERT_NUM INTEGER," +
|
"CERT_NUM INTEGER," +
|
||||||
"QUANTITY INTEGER," +
|
"QUANTITY INTEGER," +
|
||||||
|
"NOTES TEXT," +
|
||||||
"PRIMARY KEY(PCGS_NUMBER, GRADE))";
|
"PRIMARY KEY(PCGS_NUMBER, GRADE))";
|
||||||
|
|
||||||
// Execute the command.
|
// Execute the command.
|
||||||
cmd.ExecuteNonQuery();
|
cmd.ExecuteNonQuery();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void InsertCoin(Coin newCoin) {
|
public void InsertCoin(Coin coin) {
|
||||||
|
Console.WriteLine("Inserting coin...");
|
||||||
// Use our existing connection to insert a coin to the database.
|
// Use our existing connection to insert a coin to the database.
|
||||||
if (!IsConnected) {
|
if (!IsConnected) {
|
||||||
// TODO Create a NotConnectedToDatabaseException
|
// TODO Create a NotConnectedToDatabaseException
|
||||||
@@ -82,44 +101,63 @@ public class CoinDatabase {
|
|||||||
"INSERT INTO CollectionTable (PCGS_NUMBER, GRADE, YEAR," +
|
"INSERT INTO CollectionTable (PCGS_NUMBER, GRADE, YEAR," +
|
||||||
"DENOMINATION, MINT_MARK, PRICE_GUIDE_VALUE, COIN_FACTS_LINK," +
|
"DENOMINATION, MINT_MARK, PRICE_GUIDE_VALUE, COIN_FACTS_LINK," +
|
||||||
"MAJOR_VARIETY, MINOR_VARIETY, DIE_VARIETY, SERIES_NAME, CATEGORY, DESIGNATION," +
|
"MAJOR_VARIETY, MINOR_VARIETY, DIE_VARIETY, SERIES_NAME, CATEGORY, DESIGNATION," +
|
||||||
"CERT_NUM, QUANTITY) " +
|
"CERT_NUM, QUANTITY, NOTES) " +
|
||||||
"VALUES (@PcgsNumber, @Grade, @Year, @Denomination, @MintMark, @PriceGuideValue," +
|
$"VALUES ('{coin.PCGSNo}', '{coin.Grade}', {coin.Year}, '{coin.Denomination}', '{coin.MintMark}', {coin.PriceGuideValue}," +
|
||||||
"@CoinFactsLink, @MajorVariety, @MinorVariety, @DieVariety, @SeriesName, @Category, @Designation," +
|
$"'{coin.CoinFactsLink}', '{coin.MajorVariety}', '{coin.MinorVariety}', '{coin.DieVariety}', '{coin.SeriesName}', " +
|
||||||
"@CertificateNumber, @Quantity)";
|
$"'{coin.Category}', '{coin.Designation}', {coin.CertificateNumber}, {coin.Quantity}, @Notes)";
|
||||||
cmd.Parameters.AddWithValue("@PcgsNumber", newCoin.PCGSNo);
|
cmd.Parameters.AddWithValue("@Notes", coin.Notes);
|
||||||
cmd.Parameters.AddWithValue("@Grade", newCoin.Grade);
|
|
||||||
cmd.Parameters.AddWithValue("@Year", newCoin.Year);
|
|
||||||
cmd.Parameters.AddWithValue("@Denomination", newCoin.Denomination);
|
|
||||||
cmd.Parameters.AddWithValue("@MintMark", newCoin.MintMark);
|
|
||||||
cmd.Parameters.AddWithValue("@PriceGuideValue", newCoin.PriceGuideValue);
|
|
||||||
cmd.Parameters.AddWithValue("@CoinFactsLink", newCoin.CoinFactsLink);
|
|
||||||
cmd.Parameters.AddWithValue("@MajorVariety", newCoin.MajorVariety);
|
|
||||||
cmd.Parameters.AddWithValue("@MinorVariety", newCoin.MinorVariety);
|
|
||||||
cmd.Parameters.AddWithValue("@DieVariety", newCoin.DieVariety);
|
|
||||||
cmd.Parameters.AddWithValue("@SeriesName", newCoin.SeriesName);
|
|
||||||
cmd.Parameters.AddWithValue("@Category", newCoin.Category);
|
|
||||||
cmd.Parameters.AddWithValue("@Designation", newCoin.Designation);
|
|
||||||
cmd.Parameters.AddWithValue("@CertificateNumber", newCoin.CertificateNumber);
|
|
||||||
cmd.Parameters.AddWithValue("@Quantity", newCoin.Quantity);
|
|
||||||
|
|
||||||
// Execute the command.
|
// Execute the command.
|
||||||
cmd.ExecuteNonQuery();
|
cmd.ExecuteNonQuery();
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Coin> GetCollection(string collectionName) {
|
public async void CreateCoin(int pcgsNumber, string grade, int quantity) {
|
||||||
|
Console.WriteLine("Creating coin...");
|
||||||
|
// Create a coin by calling the API, then insert it into the database.
|
||||||
|
// First, check if the coin already exists - if it does, just update the quantity by adding the amount entered.
|
||||||
|
var coin = GetCoin(pcgsNumber, grade);
|
||||||
|
if (coin is not null) {
|
||||||
|
coin.Quantity += quantity;
|
||||||
|
SaveCoin("CollectionTable", coin);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Build a new coin with the API and insert it.
|
||||||
|
var newCoin = await _pcgsClient.GetCoinFactsByGrade(pcgsNumber, grade);
|
||||||
|
newCoin.Quantity = quantity;
|
||||||
|
InsertCoin(newCoin);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Coin? GetCoin(int pcgsNumber, string grade) {
|
||||||
|
Console.WriteLine($"Getting coin {pcgsNumber}, {grade}...");
|
||||||
|
int gradeInt = GetGradeFromString(grade);
|
||||||
|
|
||||||
|
// Check the collection to see if the coin exists.
|
||||||
|
// We can't make a more efficient algorithm since there's not really an ordering to the collection.
|
||||||
|
foreach (var coin in Collection) {
|
||||||
|
if (coin.PCGSNo == pcgsNumber.ToString() && coin.Grade.Contains(gradeInt.ToString())) { // This has the possibility of a false positive for single digit grades.
|
||||||
|
if (gradeInt < 10)
|
||||||
|
if (char.IsDigit(coin.Grade[3])) continue; // TODO For right now, we're going to assume that the first 2 characters are ciruclation strings, and the next 2 are grade numbers.
|
||||||
|
Console.WriteLine("Found coin.");
|
||||||
|
return coin;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Console.WriteLine("Couldn't find coin.");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void GetCollection(string collectionName) {
|
||||||
|
Console.WriteLine("Getting collection...");
|
||||||
SQLiteCommand cmd = Connection.CreateCommand();
|
SQLiteCommand cmd = Connection.CreateCommand();
|
||||||
cmd.CommandText = $"SELECT * FROM {collectionName}";
|
cmd.CommandText = $"SELECT * FROM {collectionName}";
|
||||||
|
|
||||||
var coins = new List<Coin>();
|
|
||||||
|
|
||||||
using (var reader = cmd.ExecuteReader()) {
|
using (var reader = cmd.ExecuteReader()) {
|
||||||
while (reader.Read()) {
|
while (reader.Read()) {
|
||||||
// Create coin from reader then add to list.
|
// Create coin from reader then add to list.
|
||||||
coins.Add(CoinFromReader(reader));
|
Collection.Add(CoinFromReader(reader));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return coins;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String CollectionToCSV(string collectionName) {
|
public String CollectionToCSV(string collectionName) {
|
||||||
@@ -163,54 +201,70 @@ public class CoinDatabase {
|
|||||||
resultString += "NULL" + ",";
|
resultString += "NULL" + ",";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
resultString += "\n";
|
resultString += "\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return resultString;
|
return resultString;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Coin? GetCoin(int pcgsNumber, string grade) {
|
public void SaveCoin(string collectionName, Coin coin) {
|
||||||
// Get the coin based off of the pcgs number.
|
// Get and replace the coin from the database.
|
||||||
|
Console.WriteLine("Saving coin...");
|
||||||
SQLiteCommand cmd = Connection.CreateCommand();
|
SQLiteCommand cmd = Connection.CreateCommand();
|
||||||
cmd.CommandText = "SELECT * FROM CollectionTable WHERE Id = @Id AND Grade = @Grade";
|
cmd.CommandText = $"UPDATE {collectionName} " +
|
||||||
cmd.Parameters.AddWithValue("@Id", pcgsNumber);
|
$"SET YEAR = {coin.Year}, " +
|
||||||
cmd.Parameters.AddWithValue("@Grade", grade);
|
$"DENOMINATION = \'{coin.Denomination}\', " +
|
||||||
|
$"MINT_MARK = \'{coin.MintMark}\', " +
|
||||||
Coin? returnCoin = null;
|
$"PRICE_GUIDE_VALUE = \'{coin.PriceGuideValue}\', " +
|
||||||
|
$"COIN_FACTS_LINK = \'{coin.CoinFactsLink}\', " +
|
||||||
|
$"MAJOR_VARIETY = \'{coin.MajorVariety}\', " +
|
||||||
|
$"MINOR_VARIETY = \'{coin.MinorVariety}\', " +
|
||||||
|
$"DIE_VARIETY = \'{coin.DieVariety}\', " +
|
||||||
|
$"SERIES_NAME = \'{coin.SeriesName}\', " +
|
||||||
|
$"CATEGORY = \'{coin.Category}\', " +
|
||||||
|
$"DESIGNATION = \'{coin.Designation}\', " +
|
||||||
|
$"CERT_NUM = \'{coin.CertificateNumber}\', " +
|
||||||
|
$"QUANTITY = {coin.Quantity}, " +
|
||||||
|
$"NOTES = @Notes " +
|
||||||
|
$"WHERE PCGS_NUMBER = {coin.PCGSNo} AND GRADE = \'{coin.Grade}\'";
|
||||||
|
cmd.Parameters.AddWithValue("@Notes", coin.Notes);
|
||||||
|
Console.WriteLine(cmd.CommandText);
|
||||||
// Execute the command.
|
// Execute the command.
|
||||||
using (var reader = cmd.ExecuteReader()) {
|
cmd.ExecuteNonQuery();
|
||||||
while (reader.Read()) {
|
}
|
||||||
returnCoin = CoinFromReader(reader);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return returnCoin;
|
public void UpdateCollection(string collectionName) {
|
||||||
|
// Update the database with the contents of the collection.
|
||||||
|
// TODO This is a very inefficient way of doing this. I should be able to do this in one command.
|
||||||
|
foreach (var coin in Collection) {
|
||||||
|
SaveCoin(collectionName, coin); // CAREFUL! This will not create a coin if it doesn't currently exist.
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Coin CoinFromReader(SQLiteDataReader reader) {
|
private Coin CoinFromReader(SQLiteDataReader reader) {
|
||||||
|
// Create a coin while filtering out any possible null values - they throw exceptions.
|
||||||
Coin coin = new Coin();
|
Coin coin = new Coin();
|
||||||
coin.PCGSNo = reader.GetString(0);
|
if (!reader.IsDBNull(0)) coin.PCGSNo = reader.GetString(0);
|
||||||
coin.Grade = reader.GetString(1);
|
if (!reader.IsDBNull(1)) coin.Grade = reader.GetString(1);
|
||||||
coin.Year = reader.GetInt32(2);
|
if (!reader.IsDBNull(2)) coin.Year = reader.GetInt32(2);
|
||||||
coin.Denomination = reader.GetString(3);
|
if (!reader.IsDBNull(3)) coin.Denomination = reader.GetString(3);
|
||||||
coin.MintMark = reader.GetString(4);
|
if (!reader.IsDBNull(4)) coin.MintMark = reader.GetString(4);
|
||||||
coin.PriceGuideValue = reader.GetDouble(5);
|
if (!reader.IsDBNull(5)) coin.PriceGuideValue = reader.GetDouble(5);
|
||||||
coin.CoinFactsLink = reader.GetString(6);
|
if (!reader.IsDBNull(6)) coin.CoinFactsLink = reader.GetString(6);
|
||||||
coin.MajorVariety = reader.GetString(7);
|
if (!reader.IsDBNull(7)) coin.MajorVariety = reader.GetString(7);
|
||||||
coin.MinorVariety = reader.GetString(8);
|
if (!reader.IsDBNull(8)) coin.MinorVariety = reader.GetString(8);
|
||||||
coin.DieVariety = reader.GetString(9);
|
if (!reader.IsDBNull(9)) coin.DieVariety = reader.GetString(9);
|
||||||
coin.SeriesName = reader.GetString(10);
|
if (!reader.IsDBNull(10)) coin.SeriesName = reader.GetString(10);
|
||||||
coin.Category = reader.GetString(11);
|
if (!reader.IsDBNull(11)) coin.Category = reader.GetString(11);
|
||||||
coin.Designation = reader.GetString(12);
|
if (!reader.IsDBNull(12)) coin.Designation = reader.GetString(12);
|
||||||
coin.CertificateNumber = reader.GetInt32(13);
|
if (!reader.IsDBNull(13)) coin.CertificateNumber = reader.GetInt32(13);
|
||||||
coin.Quantity = reader.GetInt32(14);
|
if (!reader.IsDBNull(14)) coin.Quantity = reader.GetInt32(14);
|
||||||
|
if (!reader.IsDBNull(15)) coin.Notes = reader.GetString(15);
|
||||||
coin.TotalPrice = coin.Quantity * coin.PriceGuideValue;
|
coin.TotalPrice = coin.Quantity * coin.PriceGuideValue;
|
||||||
return coin;
|
return coin;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DeleteCoin(Coin delCoin) {
|
public void DeleteCoin(Coin delCoin) {
|
||||||
SQLiteCommand cmd = Connection.CreateCommand();
|
SQLiteCommand cmd = Connection.CreateCommand();
|
||||||
cmd.CommandText = "DELETE FROM CollectionTable WHERE PCGS_NUMBER = @PcgsNumber AND GRADE = @Grade";
|
cmd.CommandText = "DELETE FROM CollectionTable WHERE PCGS_NUMBER = @PcgsNumber AND GRADE = @Grade";
|
||||||
@@ -219,4 +273,10 @@ public class CoinDatabase {
|
|||||||
|
|
||||||
cmd.ExecuteNonQuery();
|
cmd.ExecuteNonQuery();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private int GetGradeFromString(string grade) {
|
||||||
|
var actualGrade = int.Parse(grade.Substring(grade.Length - 2));
|
||||||
|
Console.WriteLine($"Grade is {actualGrade}");
|
||||||
|
return actualGrade;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -2,16 +2,22 @@
|
|||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Net.Http.Headers;
|
using System.Net.Http.Headers;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
// using Newtonsoft.Json;
|
|
||||||
using PcgsInvUi.Models;
|
using PcgsInvUi.Models;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using System.Text.Json.Serialization;
|
using ReactiveUI;
|
||||||
|
|
||||||
|
|
||||||
namespace PcgsInvUi.Services;
|
namespace PcgsInvUi.Services;
|
||||||
|
|
||||||
public class PcgsClient {
|
public class PcgsClient : ReactiveObject {
|
||||||
|
public int NumApiRequests {
|
||||||
|
get => _numApiRequests;
|
||||||
|
set => this.RaiseAndSetIfChanged(ref _numApiRequests, value);
|
||||||
|
}
|
||||||
|
|
||||||
private string _apiUri = "https://api.pcgs.com/publicapi";
|
private string _apiUri = "https://api.pcgs.com/publicapi";
|
||||||
private readonly string _apiKey;
|
private readonly string _apiKey;
|
||||||
|
private int _numApiRequests;
|
||||||
|
|
||||||
public PcgsClient(string apiKey) {
|
public PcgsClient(string apiKey) {
|
||||||
// _apiKey = apiKey;
|
// _apiKey = apiKey;
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ using ReactiveUI;
|
|||||||
|
|
||||||
namespace PcgsInvUi.ViewModels;
|
namespace PcgsInvUi.ViewModels;
|
||||||
|
|
||||||
// TODO Error handling.
|
// TODO Error handling for API calls.
|
||||||
// TODO Manual handling of API key.
|
// TODO Manual handling of API key.
|
||||||
// TODO Use CoinFacts link.
|
// TODO Use CoinFacts link.
|
||||||
// TODO Splash screen during startup.
|
// TODO Splash screen during startup.
|
||||||
@@ -26,7 +26,6 @@ public class MainWindowViewModel : ViewModelBase {
|
|||||||
get => _sideContent;
|
get => _sideContent;
|
||||||
private set => this.RaiseAndSetIfChanged(ref _sideContent, value);
|
private set => this.RaiseAndSetIfChanged(ref _sideContent, value);
|
||||||
}
|
}
|
||||||
public ObservableCollection<Coin> CoinCollection { get; set; }
|
|
||||||
public ObservableCollection<Coin> DisplayedList { get; set; }
|
public ObservableCollection<Coin> DisplayedList { get; set; }
|
||||||
public CoinDatabase ConnectedCoinDatabase { get; set; }
|
public CoinDatabase ConnectedCoinDatabase { get; set; }
|
||||||
public Coin? SelectedCoin {
|
public Coin? SelectedCoin {
|
||||||
@@ -53,12 +52,9 @@ public class MainWindowViewModel : ViewModelBase {
|
|||||||
var newViewModel = new NewViewModel();
|
var newViewModel = new NewViewModel();
|
||||||
_sideContent = newViewModel;
|
_sideContent = newViewModel;
|
||||||
// DisplayedList = CoinCollection = new ObservableCollection<Coin>(coins.GetItems());
|
// DisplayedList = CoinCollection = new ObservableCollection<Coin>(coins.GetItems());
|
||||||
DisplayedList = CoinCollection =
|
DisplayedList = ConnectedCoinDatabase.Collection;
|
||||||
new ObservableCollection<Coin>(coins.GetCollection("CollectionTable"));
|
|
||||||
TotalValue = DisplayedList.Sum(x => x.TotalPrice);
|
TotalValue = DisplayedList.Sum(x => x.TotalPrice);
|
||||||
_pcgsClient = new PcgsClient(
|
|
||||||
"eAb8gS0I2XAvT_5gJeiGJaglMia1Tk-oB4kJUK6kuafyrny_S61vIJY-Ikl4nCQM67wrdxzUqLVWTV2kBSxD3d5XNBHxHnYBhcSS6dOPug0hZaF3qAv56df3gYSzOGh9Tif5y0eP3Iw0LrqKDr1Hj-dk6SV6GKog2IIqCPQhhHH8FMTWBTYO-_O8cx7qLdM5GM8KlTsic6g3VRUhM8EA_4OO04dCfmNLGhqINRl3jGZ0Q4ziI8fng2bVWsIyteqiPzUn10rIQ3-OPpqVZG_DxeOmOejj4GzbUNyqUOajy-nr5rYY");
|
|
||||||
|
|
||||||
// Set up the ability to open the delete window.
|
// Set up the ability to open the delete window.
|
||||||
ShowDeleteWindow = new Interaction<DeleteWindowViewModel, bool>();
|
ShowDeleteWindow = new Interaction<DeleteWindowViewModel, bool>();
|
||||||
var deleteEnabled = this.WhenAnyValue(x => x.SelectedCoin)
|
var deleteEnabled = this.WhenAnyValue(x => x.SelectedCoin)
|
||||||
@@ -68,7 +64,7 @@ public class MainWindowViewModel : ViewModelBase {
|
|||||||
var result = await ShowDeleteWindow.Handle(deleteViewModel);
|
var result = await ShowDeleteWindow.Handle(deleteViewModel);
|
||||||
if (result && SelectedCoin is not null) {
|
if (result && SelectedCoin is not null) {
|
||||||
ConnectedCoinDatabase.DeleteCoin(SelectedCoin);
|
ConnectedCoinDatabase.DeleteCoin(SelectedCoin);
|
||||||
CoinCollection.Remove(SelectedCoin); // possible null deref - ignored due to button being disabled.
|
ConnectedCoinDatabase.Collection.Remove(SelectedCoin); // possible null deref - ignored due to button being disabled.
|
||||||
}
|
}
|
||||||
}, deleteEnabled);
|
}, deleteEnabled);
|
||||||
|
|
||||||
@@ -93,16 +89,12 @@ public class MainWindowViewModel : ViewModelBase {
|
|||||||
// This is the same as the above, but with a different syntax.
|
// This is the same as the above, but with a different syntax.
|
||||||
newViewModel.OkCommand
|
newViewModel.OkCommand
|
||||||
.Subscribe(async requestStructure => {
|
.Subscribe(async requestStructure => {
|
||||||
var newCoin = await _pcgsClient.GetCoinFactsByGrade(requestStructure.Item1, requestStructure.Item2);
|
ConnectedCoinDatabase.CreateCoin(requestStructure.Item1, requestStructure.Item2, requestStructure.Item3);
|
||||||
newCoin.Quantity = requestStructure.Item3;
|
|
||||||
CoinCollection.Add(newCoin);
|
|
||||||
coins.InsertCoin(newCoin);
|
|
||||||
TotalValue += newCoin.Quantity * newCoin.PriceGuideValue;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Change TotalValue anytime SelectedCoin.TotalPrice changes.
|
// Change TotalValue anytime SelectedCoin.TotalPrice changes.
|
||||||
// Possible null deref - ignored due to null values summing to 0.
|
// Possible null deref - ignored due to null values summing to 0.
|
||||||
this.WhenAnyValue(x => x.SelectedCoin.TotalPrice)
|
this.WhenAnyValue(x => x.SelectedCoin.TotalPrice)
|
||||||
.Subscribe(_ => TotalValue = CoinCollection.Sum(x => x.TotalPrice));
|
.Subscribe(_ => TotalValue = ConnectedCoinDatabase.Collection.Sum(x => x.TotalPrice));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -14,7 +14,9 @@
|
|||||||
<Grid RowDefinitions="Auto, *">
|
<Grid RowDefinitions="Auto, *">
|
||||||
<UserControl Grid.Row="0" Margin="10, 20, 10, 10" VerticalAlignment="Center"
|
<UserControl Grid.Row="0" Margin="10, 20, 10, 10" VerticalAlignment="Center"
|
||||||
Content="{Binding SidebarContent}" />
|
Content="{Binding SidebarContent}" />
|
||||||
<TextBox Grid.Row="1" Margin="5" Watermark="Notes..." />
|
<TextBox Grid.Row="1" Margin="5" Watermark="Notes..."
|
||||||
|
Text="{Binding SelectedCoin.Notes}"
|
||||||
|
IsReadOnly="False" TextWrapping="Wrap"/>
|
||||||
</Grid>
|
</Grid>
|
||||||
</SplitView.Pane>
|
</SplitView.Pane>
|
||||||
<Grid RowDefinitions="*, Auto" ShowGridLines="False">
|
<Grid RowDefinitions="*, Auto" ShowGridLines="False">
|
||||||
|
|||||||
Reference in new issue
Block a user