diff --git a/WebServer/Components/Pages/Home.razor b/WebServer/Components/Pages/Home.razor index 354c82cf..2c3c320a 100644 --- a/WebServer/Components/Pages/Home.razor +++ b/WebServer/Components/Pages/Home.razor @@ -1,4 +1,5 @@ @page "/" +@using Controllers.Payment @rendermode InteractiveServer Home @@ -53,7 +54,10 @@ } - @PredictError + + + + @resultError } @@ -103,6 +107,15 @@ new stockPredictionPair(){ Symbol = "FUN" } }; + string PaymentKey = ""; + protected override async Task OnInitializedAsync(){ + (bool, string) result = PaymentProcessor.CreatePayment(); + if (!result.Item1){ + resultError = result.Item2; + } + PaymentKey = result.Item2; + } + async Task LoginSession(){ string dbPrefix = $"[{userName.ToLower()}]:"; // Set the DB prefix for the get and set string passwordhash = dbDriver.Get( dbPrefix + "password" ); // Pull the password hash @@ -136,11 +149,11 @@ string pullButtonText = "Pull Data"; string trainButtonText = "Train AI"; string predictButtonText = "Predict AI"; - string PredictError = ""; + string resultError = ""; bool Debounce = true; async Task pull(){ - PredictError = ""; + resultError = ""; if (Debounce){ Debounce = false; pullButtonText = "Do not refresh the page. The data is pulling."; @@ -159,7 +172,7 @@ } async Task train(){ - PredictError = ""; + resultError = ""; if (Debounce){ Debounce = false; trainButtonText = "Do not refresh the page. The AI is training."; @@ -178,7 +191,7 @@ } async Task predict(){ - PredictError = ""; + resultError = ""; if (Debounce){ Debounce = false; predictButtonText = "Do not refresh the page. The AI is predicting"; @@ -190,7 +203,7 @@ if (string.IsNullOrEmpty(Result.Item1)){ cur.Movement = Result.Item2; }else{ - PredictError = Result.Item1; + resultError = Result.Item1; } Console.WriteLine("Received Signal [" + cur.Symbol + "] : " + cur.Movement); }); @@ -205,6 +218,47 @@ } } + // Stock Manipulation + + string buyStockSymbol = ""; + string buyStockQuantity = ""; + float StockPrice = 0; + void buyStock(){ + if (Session != null){ + + // Try Parse the quantitiy input + bool success = float.TryParse(buyStockQuantity, out float QuantityResult); + if (!success){ + resultError = "Quantity field is not a number"; + return; + } + + // Try Pay for the stock + (bool, string) result = PaymentProcessor.TryPayment(PaymentKey, QuantityResult * StockPrice); + if (!result.Item1){ + resultError = result.Item2; + return; + } + + // Add the item + Session.TrackedStocks.Add( new PurchasedStock(){ + Symbol = buyStockSymbol.ToLower(), + PurchasePrice = StockPrice, + Quantity = QuantityResult, + PurchaseDate = DateTime.Now + } ); + + // Reset the Impodent Key + result = PaymentProcessor.CreatePayment(); + if (!result.Item1){ + resultError = "[Payment suceeded but new payment session failed] : " + result.Item2; + return; + } + PaymentKey = result.Item2; + + } + } + // Data Types class stockPredictionPair { diff --git a/WebServer/Components/_Imports.razor b/WebServer/Components/_Imports.razor index b1da8103..4f8bc09b 100644 --- a/WebServer/Components/_Imports.razor +++ b/WebServer/Components/_Imports.razor @@ -1,13 +1,14 @@ @using System.Net.Http @using System.Net.Http.Json -@using DataBase +@using Controllers.Payment @using Microsoft.AspNetCore.Components.Forms @using Microsoft.AspNetCore.Components.Routing @using Microsoft.AspNetCore.Components.Web @using static Microsoft.AspNetCore.Components.Web.RenderMode @using Microsoft.AspNetCore.Components.Web.Virtualization @using Microsoft.JSInterop -@using PythonInterop +@using Controllers.PythonInterop +@using Controllers.DataBase @using WebServer @using WebServer.Components @using BCrypt.Net; @@ -15,3 +16,4 @@ @inject DbDriver dbDriver @inject AIModule aiModule +@inject IPayment PaymentProcessor diff --git a/WebServer/Controllers/Database.cs b/WebServer/Controllers/Database.cs index 196d9deb..2fa972fc 100644 --- a/WebServer/Controllers/Database.cs +++ b/WebServer/Controllers/Database.cs @@ -1,6 +1,6 @@ using Microsoft.Data.Sqlite; -namespace DataBase { +namespace Controllers.DataBase { public class DbDriver { diff --git a/WebServer/Controllers/Payments/IPayments.cs b/WebServer/Controllers/Payments/IPayments.cs new file mode 100644 index 00000000..3194747a --- /dev/null +++ b/WebServer/Controllers/Payments/IPayments.cs @@ -0,0 +1,13 @@ +namespace Controllers.Payment { + + public interface IPayment { + + // [ Success, ErrorMessage | ImpodentKey ] + public (bool, string) CreatePayment(); + + // [ Success, ErrorMessage ] + public (bool, string) TryPayment(string ImpodentKey, float Price); + + } + +} \ No newline at end of file diff --git a/WebServer/Controllers/Payments/PaymentTester.cs b/WebServer/Controllers/Payments/PaymentTester.cs new file mode 100644 index 00000000..f9da68f2 --- /dev/null +++ b/WebServer/Controllers/Payments/PaymentTester.cs @@ -0,0 +1,27 @@ +namespace Controllers.Payment { + + public class PaymentTestor : IPayment { + + public static List ImpodentKeys = new List(); + + public (bool, string) CreatePayment() { + string guid = Guid.NewGuid().ToString(); + ImpodentKeys.Add(guid); + return (true, guid); + } + + public (bool, string) TryPayment(string ImpodentKey, float Price) { + try { + if (ImpodentKeys.Contains(ImpodentKey)) { + ImpodentKeys.Remove(ImpodentKey); + return (true, ""); + } else { + return (false, "Payment session closed or never existed"); + } + }catch(Exception e) { + return (false, e.ToString()); + } + } + } + +} \ No newline at end of file diff --git a/WebServer/Controllers/PythonInterop.cs b/WebServer/Controllers/PythonInterop.cs index 022f51b1..9958c158 100644 --- a/WebServer/Controllers/PythonInterop.cs +++ b/WebServer/Controllers/PythonInterop.cs @@ -1,6 +1,6 @@ using Python.Runtime; -namespace PythonInterop { +namespace Controllers.PythonInterop { public class AIModule { diff --git a/WebServer/Program.cs b/WebServer/Program.cs index 3448ff19..5227cbb4 100644 --- a/WebServer/Program.cs +++ b/WebServer/Program.cs @@ -1,6 +1,7 @@ using WebServer.Components; -using PythonInterop; -using DataBase; +using Controllers.PythonInterop; +using Controllers.DataBase; +using Controllers.Payment; // Load the module in globally and use correct path for local or docker runners #if DEBUG @@ -21,6 +22,11 @@ if (args.Contains("Pull-Stock-Data")) { // Insert the DB driver for Dependency Injection builder.Services.AddScoped(); + // Insert the payment Processor + builder.Services.AddSingleton( + new PaymentTestor() // Of type Payment Testor -> Change this with stripe or square in the future + ); + // Insert the python modlue for Dependency Injection builder.Services.AddSingleton(interopModule);