diff --git a/Boluwatife/StageTwoTask/BankProject.sln b/Boluwatife/StageTwoTask/BankProject.sln new file mode 100644 index 0000000..cecb6d6 --- /dev/null +++ b/Boluwatife/StageTwoTask/BankProject.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.32014.148 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BankProject", "BankProject\BankProject.csproj", "{16C39874-DEFF-4271-9CE0-336111B0F833}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {16C39874-DEFF-4271-9CE0-336111B0F833}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {16C39874-DEFF-4271-9CE0-336111B0F833}.Debug|Any CPU.Build.0 = Debug|Any CPU + {16C39874-DEFF-4271-9CE0-336111B0F833}.Release|Any CPU.ActiveCfg = Release|Any CPU + {16C39874-DEFF-4271-9CE0-336111B0F833}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {123C7F3B-1B1C-48B0-9654-68ABF2074ED3} + EndGlobalSection +EndGlobal diff --git a/Boluwatife/StageTwoTask/BankProject/AppServices/ITransaction.cs b/Boluwatife/StageTwoTask/BankProject/AppServices/ITransaction.cs new file mode 100644 index 0000000..f233b6f --- /dev/null +++ b/Boluwatife/StageTwoTask/BankProject/AppServices/ITransaction.cs @@ -0,0 +1,17 @@ +using BankProject.Domain.Enums; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BankProject.AppServices +{ + public interface ITransaction + { + void InsertTransaction(long _userBankAccountId, TransactionType _tranType, decimal _tranAmount, string _desc); + void ViewTransaction(); + + + } +} diff --git a/Boluwatife/StageTwoTask/BankProject/AppServices/IUserAccountActions.cs b/Boluwatife/StageTwoTask/BankProject/AppServices/IUserAccountActions.cs new file mode 100644 index 0000000..3ce5ad2 --- /dev/null +++ b/Boluwatife/StageTwoTask/BankProject/AppServices/IUserAccountActions.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BankProject.AppServices +{ + public interface IUserAccountActions + { + void CheckBalance(); + void PlaceDeposit(); + void MakeWithDrawal(); + + } +} diff --git a/Boluwatife/StageTwoTask/BankProject/AppServices/IUserLogin.cs b/Boluwatife/StageTwoTask/BankProject/AppServices/IUserLogin.cs new file mode 100644 index 0000000..8d4d5fe --- /dev/null +++ b/Boluwatife/StageTwoTask/BankProject/AppServices/IUserLogin.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BankProject.AppServices +{ + public interface IUserLogin + { + void CheckUserCardNumAndPassword(); + } +} diff --git a/Boluwatife/StageTwoTask/BankProject/AppServices/UserServices.cs b/Boluwatife/StageTwoTask/BankProject/AppServices/UserServices.cs new file mode 100644 index 0000000..f3c7df4 --- /dev/null +++ b/Boluwatife/StageTwoTask/BankProject/AppServices/UserServices.cs @@ -0,0 +1,507 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using BankProject.Display; +using BankProject.Domain.Enitities; +using BankProject.Domain.Enums; +using ConsoleTables; +using Newtonsoft.Json; + +namespace BankProject.AppServices +{ + public class UserServices : IUserLogin, IUserAccountActions, ITransaction + { + // private List userAccountList; + private List userAccountList; + private UserAccount selectedAccount; + private List _ListOfTransactions; + + private const decimal minimumKeptAmount = 500; + + private readonly AppScreen screen; + + public UserServices() + { + screen = new AppScreen(); + userAccountList = new List(); + } + + + + public void OnBoard() + { + Console.WriteLine("Do you have an account, if NO enter 1 to REGISTER if YES enter 2 to LOGIN..."); + + switch (Validator.Convert("an option:")) + { + case (int)OnBoarding.Register: + Regiser(); + break; + case (int)OnBoarding.Login: + Run(); + break; + default: + Utility.PrintMessage("Invalid Options..", false); + break; + } + + + } + + public void Run() + { + AppScreen.Welcome(); + + CheckUserCardNumAndPassword(); + + AppScreen.WelcomeCustomer(selectedAccount.FullName); + while (true) + { + AppScreen.DisplaayAppMenu(); + + ProcessMenuoption(); + } + + } + + + public void Regiser() + { + AddNewMember(); + InitializeData(); + Run(); + } + + + public void AddNewMember() + { + string filePath = @"C:\Users\USER\Desktop\Project\BankProject\BankProject\Test.txt"; + List lines = File.ReadAllLines(filePath).ToList(); + List UserAccountList = new List(); + + int id; + string fullName; + long accountNumber; + long cardNumber; + int cardPin; + decimal accountBalance; + int totalLogin; + bool isLocked; + + Console.WriteLine("Kindly fill in the following details"); + Console.WriteLine(""); + Console.WriteLine("Kindly fill in your Id: "); + id = Convert.ToInt32(Console.ReadLine()); + Console.WriteLine("Kindly fill in your fullname: "); + fullName = Console.ReadLine(); + Console.WriteLine("Kindly fill in your accountNumber: "); + accountNumber = long.Parse(Console.ReadLine()); + Console.WriteLine("Kindly fill in your Card Number: "); + cardNumber = long.Parse(Console.ReadLine()); + Console.WriteLine("fill in yur card pin:"); + cardPin = Convert.ToInt32(Console.ReadLine()); + Console.WriteLine("fill you your first deposite: "); + accountBalance = long.Parse(Console.ReadLine()); + Console.WriteLine("fill in you total login as 0"); + totalLogin = Convert.ToInt32(Console.ReadLine()); + Console.WriteLine("locked access count: "); + isLocked = bool.Parse(Console.ReadLine()); + + UserAccountList.Add(new UserAccount + { + Id = id, + FullName = fullName, + AccountNumber = accountNumber, + CardNumber = cardNumber, + CardPin = cardPin, + AccountBalance = accountBalance, + TotalLogin = totalLogin, + IsLocked = isLocked + }); + + List output = new List(); + + foreach (var userAccount in UserAccountList) + { + output.Add($"{userAccount.Id},{userAccount.FullName},{userAccount.AccountNumber}," + + $"{userAccount.CardNumber}, {userAccount.CardPin}," + + $"{userAccount.AccountBalance}, {userAccount.TotalLogin}," + + $"{userAccount.IsLocked}"); + } + Console.WriteLine("Writting to text file"); + + File.AppendAllLines(filePath, output); + + // File.WriteAllLines(filePath, output); + + Console.WriteLine("All entries"); + + Console.WriteLine("done....."); + + } + + + public void InitializeData() + { + string filePath = @"C:\Users\USER\Desktop\Project\BankProject\BankProject\Test.txt"; + List UserAccountList = new List(); + List lines = File.ReadAllLines(filePath).ToList(); + foreach (string line in lines) + { + string[] entries = line.Split(','); + UserAccount userAccount = new UserAccount(); + + userAccount.Id = int.Parse(entries[0]); + userAccount.FullName = entries[1]; + userAccount.AccountNumber = long.Parse(entries[2]); + userAccount.CardNumber = long.Parse(entries[3]); + userAccount.CardPin = Int32.Parse(entries[4]); + userAccount.AccountBalance = Convert.ToDecimal(entries[5]); + userAccount.TotalLogin = int.Parse(entries[6]); + userAccount.IsLocked = bool.Parse(entries[7]); + + userAccountList.Add(userAccount); + } + +//1,Adebanjo Olaide,123456,321321,123123,5000.00,0,false +//2,Folorunso Nene,456789,654654,456456 ,4000.00,0,false +//3,Olatunji Money,987654,987987,789789,3000.00,1,true + + // userAccountList = new List + //{ + // new UserAccount{Id = 1, FullName = "Adebanjo Olaide", AccountNumber = 123456, CardNumber = 321321, CardPin = 123123, AccountBalance = 5000.00m, IsLocked=false}, + // new UserAccount{Id = 2, FullName = "Folorunso Nene", AccountNumber = 456789, CardNumber = 654654, CardPin = 456456 , AccountBalance = 4000.00m, IsLocked=false}, + // new UserAccount{Id = 3, FullName = "Olatunji Money", AccountNumber = 987654, CardNumber = 987987, CardPin = 789789, AccountBalance = 3000.00m, IsLocked=true}, + // }; + _ListOfTransactions = new List(); + + } + + public void CheckUserCardNumAndPassword() + { + int count = 0; + bool isCorrectLogin = false; + while (isCorrectLogin == false) + { + UserAccount inputAccount = AppScreen.UserLoginForm(); + AppScreen.LoginProgress(); + + + /// + //if + + //// + foreach (UserAccount account in userAccountList) + { + count++; + selectedAccount = account; + if (inputAccount.CardNumber.Equals(selectedAccount.CardNumber)) + { + selectedAccount.TotalLogin++; + + if (inputAccount.CardPin.Equals(selectedAccount.CardPin)) + { + selectedAccount = account; + + if (selectedAccount.IsLocked || selectedAccount.TotalLogin > 3) + { + AppScreen.PrintLockScreen(); + } + else + { + selectedAccount.TotalLogin = 0; + isCorrectLogin = true; + break; + } + } + } + if (count < userAccountList.Count) + { + continue; + } + if (count >= userAccountList.Count) + { + if (isCorrectLogin == false) + { + Utility.PrintMessage("\nInvalid card number or PIN.", false); + selectedAccount.IsLocked = selectedAccount.TotalLogin == 3; + if (selectedAccount.IsLocked) + { + AppScreen.PrintLockScreen(); + } + } + } + ///if not end of the list do not go futher untill you check the whole list + //if (isCorrectLogin == false) + //{ + // Utility.PrintMessage("\nInvalid card number or PIN.", false); + // selectedAccount.IsLocked = selectedAccount.TotalLogin == 3; + // if (selectedAccount.IsLocked) + // { + // AppScreen.PrintLockScreen(); + // } + //} + Console.Clear(); + } + } + + } + + private void ProcessMenuoption() + { + switch(Validator.Convert("an option:")) + { + case (int)BankAppMenu.CheckBalance: + CheckBalance(); + break; + case (int)BankAppMenu.PlaceDeposit: + PlaceDeposit(); + break; + case (int)BankAppMenu.MakeWithdrawal: + MakeWithDrawal(); + break; + case (int)BankAppMenu.InternalTransfer: + var internalTransfer = screen.InternalTransferForm(); + ProcessInternalTransfer(internalTransfer); + break; + case (int)BankAppMenu.ViewTransaction: + ViewTransaction(); + break; + case (int)BankAppMenu.Logout: + AppScreen.LogOutProgress(); + Utility.PrintMessage("You have successfully logged out.", true); + Run(); + break; + default: + Utility.PrintMessage("Invalid Options..", false); + break; + } + } + + //check balance + public void CheckBalance() + { + Utility.PrintMessage($"Your account balance is: {Utility.FormatAmount(selectedAccount.AccountBalance)}", true); + } + + public void PlaceDeposit() + { + Console.WriteLine("\nOnly multiple of 500 and 1000 naira allowed.\n"); + + var transaction_amt = Validator.Convert($"amount {AppScreen.cur}"); + + //simulate counting + Console.WriteLine("\nChecking and Counting bank notes."); + Utility.PrintDotAnimation(); + + Console.WriteLine(""); + + if(transaction_amt <= 0) + { + Utility.PrintMessage("Amount needs to be greater than 0", false); + return; + } + if (transaction_amt % 500 != 0) + { + Utility.PrintMessage($"Enter deposit amount of mutiple of 500 or 1000. Tray again.", false); + return; + } + + if (PreviewBankNotesCount(transaction_amt) == false) + { + Utility.PrintMessage($"You have cancalled your action.", false); + return; + } + + //bind transaction detatails to the transaction object + InsertTransaction(selectedAccount.Id, TransactionType.Deposit, transaction_amt, ""); + + //Update Account balance + selectedAccount.AccountBalance += transaction_amt; + + //print success message to the screen + Utility.PrintMessage($"Your deposit of {Utility.FormatAmount(transaction_amt)} was successful", true); + + + } + + + //Make withdrawal method + public void MakeWithDrawal() + { + var transaction_amt = 0; + int selectedAmount = AppScreen.SelectAmonunt(); + + if (selectedAmount == -1) + { + //reccuive calling of the same method. + MakeWithDrawal(); + return; + } + else if (selectedAmount != 0) + { + transaction_amt = selectedAmount; + } + else + { + //if user select 0 + transaction_amt = Validator.Convert($"amount{AppScreen.cur}"); + } + + //input validation + if(transaction_amt <= 0) + { + Utility.PrintMessage("Amount must be greater than zero.", false); + return; + } + if (transaction_amt % 500 != 0) + { + Utility.PrintMessage("You can only Withdraw amount in multiples of 5000 or 1000", false); + return; + } + + //Logic validations + if(transaction_amt > selectedAccount.AccountBalance) + { + Utility.PrintMessage($"Withdralal failed. Your balance is too low {Utility.FormatAmount(transaction_amt)}", false); + return; + } + + if ((selectedAccount.AccountBalance - transaction_amt) < minimumKeptAmount) + { + Utility.PrintMessage($"Withdrawal failed. Your account needs to have " + + $"minimum {Utility.FormatAmount(minimumKeptAmount)}", false); + return; + } + + //Bind withdrawal details to transaction object + InsertTransaction(selectedAccount.Id, TransactionType.Withdrawal, -transaction_amt, ""); + //update account balance + selectedAccount.AccountBalance -= transaction_amt; + //success message + Utility.PrintMessage($"You have successfully withdrawn " + + $"{Utility.FormatAmount(transaction_amt)}.", true); + + } + + + private bool PreviewBankNotesCount(int amount) + { + int thousandNotesCount = amount / 1000; + int fiveHundredNotesCount = (amount % 1000) / 500; + + Console.WriteLine("\nSummary"); + Console.WriteLine("-------"); + Console.WriteLine($"{AppScreen.cur}1000 X {thousandNotesCount} = {1000 * thousandNotesCount}"); + Console.WriteLine($"{AppScreen.cur}500 X {fiveHundredNotesCount} = {500 * fiveHundredNotesCount}"); + Console.WriteLine($"Total amount: {Utility.FormatAmount(amount)}\n\n"); + + int opt = Validator.Convert("1 to confirm"); + return opt.Equals(1); + + } + + public void InsertTransaction(long _userBankAccountId, TransactionType _tranType, decimal _tranAmount, string _desc) + { + //Create a new Transaction object + var transaction = new Transaction() + { + TransactionId = Utility.GetTransactionId(), + UserBankAccountId = _userBankAccountId, + TransactionDate = DateTime.Now, + TransactionType = _tranType, + TransactionAmount = _tranAmount, + Descriprion = _desc + }; + + _ListOfTransactions.Add(transaction); + } + + public void ViewTransaction() + { + var filteredTransactionList = _ListOfTransactions.Where(t => t.UserBankAccountId == selectedAccount.Id).ToList(); + //check if there's a transaction + if (filteredTransactionList.Count <= 0) + { + Utility.PrintMessage("You have no transaction yet.", true); + } + else + { + //Install a console table to draw the table. + var table = new ConsoleTable("Id", "Transaction Date", "Type", "Descriptions", "Amount " + AppScreen.cur); + foreach (var tran in filteredTransactionList) + { + table.AddRow(tran.TransactionId, tran.TransactionDate, tran.TransactionType, tran.Descriprion, tran.TransactionAmount); + } + table.Options.EnableCount = false; + table.Write(); + Utility.PrintMessage($"You have {filteredTransactionList.Count} transaction(s)", true); + } + + } + + private void ProcessInternalTransfer(InternalTransfer internalTransfer) + { + if (internalTransfer.TransferAmount <= 0) + { + Utility.PrintMessage("Amount needs to be more than 0. Try again", false); + return; + } + + //check sender's account balance + if(internalTransfer.TransferAmount > selectedAccount.AccountBalance) + { + Utility.PrintMessage($"Transfered failed, Insufficeint funds{Utility.FormatAmount(internalTransfer.TransferAmount)}", false); + return; + } + + //check the minimum kept amount + if ((selectedAccount.AccountBalance - internalTransfer.TransferAmount) < minimumKeptAmount) + { + Utility.PrintMessage($"Transfer faile. Your account needs to have minimum" + + $" {Utility.FormatAmount(minimumKeptAmount)}", false); + return; + } + + //check reciever's account number is valid *************************************************************** + var selectedBankAccountReciever = (from userAcc in userAccountList + where userAcc.AccountNumber == internalTransfer.ReciepeintBankAccountNumber + select userAcc).FirstOrDefault(); + if (selectedBankAccountReciever == null) + { + Utility.PrintMessage("Transfer failed. Recieber bank account number is invalid.", false); + return; + } + //check receiver's name + if (selectedBankAccountReciever.FullName != internalTransfer.RecipientBankAccountName) + { + Utility.PrintMessage("Transfer Failed. Recipient's bank account name does not match.", false); + return; + } + + //add transaction to transactions record- sender + InsertTransaction(selectedAccount.Id, TransactionType.Transfer, -internalTransfer.TransferAmount, "Transfered " + + $"to {selectedBankAccountReciever.AccountNumber} ({selectedBankAccountReciever.FullName})"); + //update sender's account balance + selectedAccount.AccountBalance -= internalTransfer.TransferAmount; + + //add transaction record-reciever + InsertTransaction(selectedBankAccountReciever.Id, TransactionType.Transfer, internalTransfer.TransferAmount, "Transfered from " + + $"{selectedAccount.AccountNumber}({selectedAccount.FullName})"); + //update reciever's account balance + selectedBankAccountReciever.AccountBalance += internalTransfer.TransferAmount; + //print success message + Utility.PrintMessage($"You have successfully transfered" + + $" {Utility.FormatAmount(internalTransfer.TransferAmount)} to " + + $"{internalTransfer.RecipientBankAccountName}", true); + + } + } + +} + + + + diff --git a/Boluwatife/StageTwoTask/BankProject/BankProject.csproj b/Boluwatife/StageTwoTask/BankProject/BankProject.csproj new file mode 100644 index 0000000..b0d0642 --- /dev/null +++ b/Boluwatife/StageTwoTask/BankProject/BankProject.csproj @@ -0,0 +1,15 @@ + + + + Exe + net6.0 + enable + enable + + + + + + + + diff --git a/Boluwatife/StageTwoTask/BankProject/Display/AppScreen.cs b/Boluwatife/StageTwoTask/BankProject/Display/AppScreen.cs new file mode 100644 index 0000000..6420d63 --- /dev/null +++ b/Boluwatife/StageTwoTask/BankProject/Display/AppScreen.cs @@ -0,0 +1,148 @@ +using BankProject.Domain.Enitities; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BankProject.Display +{ + public class AppScreen + { + internal const string cur = "N "; + + public static void Welcome() + { + //clears the console Screen + Console.Clear(); + //Sets the title of the console window + Console.Title = "My Bank APP"; + + //set the Text color to white + Console.ForegroundColor = ConsoleColor.White; + + //Welcome message + Console.WriteLine("\n\n -------------Welcome to My Bank APP-------------\n\n"); + + //Prompt the user to insert ATM + Console.WriteLine("Please Enter your Bank Card Number"); + + Console.WriteLine("Note: We don't accept physical card"); + + Utility.PressEnterToContinue(); + + } + + internal static UserAccount UserLoginForm() + { + UserAccount tempUserAccount = new UserAccount(); + + tempUserAccount.CardNumber = Validator.Convert("Your Bank Account card number..."); + + //Hidden input to mask pin. + tempUserAccount.CardPin = Convert.ToInt32(Utility.GetSecretInput("Enter your Card PIN")); + + return tempUserAccount; + } + + internal static void LoginProgress() + { + Console.WriteLine("\nChecking card number and Pin....."); + + Utility.PrintDotAnimation(); + + } + + internal static void PrintLockScreen() + { + Console.Clear(); + Utility.PrintMessage("Your account has been locked", true); + + Utility.PressEnterToContinue(); + Environment.Exit(1); + } + + internal static void WelcomeCustomer(string fullName) + { + Console.WriteLine($"Welcome back,{fullName}."); + } + + internal static void DisplaayAppMenu() + { + Console.Clear(); + Console.WriteLine("---------My Bank APP Menu----------"); + Console.WriteLine(": "); + Console.WriteLine("1. Account Balance :"); + Console.WriteLine("2. Cash Deposit :"); + Console.WriteLine("3. Withdrawal :"); + Console.WriteLine("4. Transfer :"); + Console.WriteLine("5. Transactions :"); + Console.WriteLine("6. Logout :"); + } + + internal static void LogOutProgress() + { + Console.WriteLine("Thank you for using My Bank APP..."); + Utility.PrintDotAnimation(); + Console.Clear(); + } + + internal static int SelectAmonunt() + { + Console.WriteLine(""); + Console.WriteLine(":1.{0}500 5.{0}10,000", cur); + Console.WriteLine(":2.{0}1000 6.{0}15,000", cur); + Console.WriteLine(":3.{0}2000 7.{0}20,000", cur); + Console.WriteLine(":4.{0}5000 8.{0}40,000", cur); + Console.WriteLine(":0.Other"); + Console.WriteLine(""); + + int selectedAmount = Validator.Convert("option:"); + switch (selectedAmount) + { + case 1: + return 500; + break; + case 2: + return 1000; + break; + case 3: + return 2000; + break; + case 4: + return 5000; + break; + case 5: + return 10000; + break; + case 6: + return 15000; + break; + case 7: + return 20000; + break; + case 8: + return 40000; + break; + case 0: + return 0; + break; + default: + Utility.PrintMessage("Invalid input. try again", false); + return -1; + break; + } + } + + + internal InternalTransfer InternalTransferForm() + { + var internalTransfer = new InternalTransfer(); + internalTransfer.ReciepeintBankAccountNumber = Validator.Convert("recipient's account number:"); + internalTransfer.TransferAmount = Validator.Convert($"amount {cur}"); + internalTransfer.RecipientBankAccountName = Utility.GetUserInput("recipient's name:"); + return internalTransfer; + } + + } +} diff --git a/Boluwatife/StageTwoTask/BankProject/Display/Utility.cs b/Boluwatife/StageTwoTask/BankProject/Display/Utility.cs new file mode 100644 index 0000000..fd2b4c7 --- /dev/null +++ b/Boluwatife/StageTwoTask/BankProject/Display/Utility.cs @@ -0,0 +1,114 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BankProject.Display +{ + public static class Utility + { + private static long tranId; + // private static CultureInfo culture = new CultureInfo("en-US"); + + + public static long GetTransactionId() + { + return ++tranId; + } + + + public static string GetSecretInput(string prompt) + { + bool isPrompt = true; + string asterics = ""; + + StringBuilder input = new StringBuilder(); + + while (true) + { + if(isPrompt) + Console.WriteLine(prompt); + + //once we promot the user for input, set it back to false + isPrompt = false; + ConsoleKeyInfo inputKey = Console.ReadKey(true); + + if (inputKey.Key == ConsoleKey.Enter) + { + if(input.Length == 6) + { + break; + } + else + { + PrintMessage("Please enter 6 digits..", false); + isPrompt = true; + input.Clear(); + continue; + } + } + + if (inputKey.Key == ConsoleKey.Backspace && input.Length > 0) + { + input.Remove(input.Length - 1, 1); + } else if(inputKey.Key != ConsoleKey.Backspace) + { + input.Append(inputKey.KeyChar); + Console.Write(asterics + "*"); + } + } + return input.ToString(); + } + + + public static void PrintMessage(string msg, bool success) + { + if (success) + { + Console.ForegroundColor = ConsoleColor.Green; + } + else + { + Console.ForegroundColor = ConsoleColor.Red; + } + Console.WriteLine(msg); + Console.ForegroundColor = ConsoleColor.White; + PressEnterToContinue(); + } + + public static string GetUserInput(string prompt) + { + Console.WriteLine($"Enter {prompt}"); + return Console.ReadLine(); + } + + public static void PrintDotAnimation(int timer = 10) + { + for (int i = 0; i < timer; i++) + { + Console.Write(".."); + Thread.Sleep(200); + } + Console.Clear(); + } + + public static void PressEnterToContinue() + { + Console.WriteLine("\n\nPress Enter to continue...\n"); + Console.ReadLine(); + } + + public static string FormatAmount(decimal amt) + { + Console.OutputEncoding = Encoding.Unicode; + //return string.Format(culture, "{0:C2}", amt); + //var culture = CultureInfo.CreateSpecificCulture("en-US"); + var culture = CultureInfo.CreateSpecificCulture("yo-NG"); + string decimalToString = amt.ToString("C", culture); + return decimalToString; + + } + } +} diff --git a/Boluwatife/StageTwoTask/BankProject/Display/Validator.cs b/Boluwatife/StageTwoTask/BankProject/Display/Validator.cs new file mode 100644 index 0000000..2b2d8f5 --- /dev/null +++ b/Boluwatife/StageTwoTask/BankProject/Display/Validator.cs @@ -0,0 +1,41 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BankProject.Display +{ + public static class Validator + { + public static T Convert(string prompt) + { + bool valid = false; + string userInput; + //while true(untill a valid input code runs continously) + while (!valid) + { + userInput = Utility.GetUserInput(prompt); + + try + { + var converter = TypeDescriptor.GetConverter(typeof(T)); + if (converter != null) + { + return (T)converter.ConvertFromString(userInput)!; + } + else + { + return default!; + } + } + catch + { + Utility.PrintMessage("Invalid input.Try again!!!.", false); + } + } + return default!; + } + } +} diff --git a/Boluwatife/StageTwoTask/BankProject/Domain/Enitities/InternalTransfer.cs b/Boluwatife/StageTwoTask/BankProject/Domain/Enitities/InternalTransfer.cs new file mode 100644 index 0000000..3544dac --- /dev/null +++ b/Boluwatife/StageTwoTask/BankProject/Domain/Enitities/InternalTransfer.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BankProject.Domain.Enitities +{ + public class InternalTransfer + { + public decimal TransferAmount { get; set; } + public long ReciepeintBankAccountNumber { get; set; } + public string RecipientBankAccountName { get; set; } + } +} diff --git a/Boluwatife/StageTwoTask/BankProject/Domain/Enitities/Transaction.cs b/Boluwatife/StageTwoTask/BankProject/Domain/Enitities/Transaction.cs new file mode 100644 index 0000000..7313ae6 --- /dev/null +++ b/Boluwatife/StageTwoTask/BankProject/Domain/Enitities/Transaction.cs @@ -0,0 +1,19 @@ +using BankProject.Domain.Enums; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BankProject.Domain.Enitities +{ + public class Transaction + { + public long TransactionId { get; set; } + public long UserBankAccountId { get; set; } + public DateTime TransactionDate { get; set; } + public TransactionType TransactionType { get; set; } + public string Descriprion { get; set; } + public Decimal TransactionAmount { get; set; } + } +} diff --git a/Boluwatife/StageTwoTask/BankProject/Domain/Enitities/UserAccount.cs b/Boluwatife/StageTwoTask/BankProject/Domain/Enitities/UserAccount.cs new file mode 100644 index 0000000..77c19a5 --- /dev/null +++ b/Boluwatife/StageTwoTask/BankProject/Domain/Enitities/UserAccount.cs @@ -0,0 +1,45 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BankProject.Domain.Enitities +{ + public class UserAccount + { + public int Id { get; set; } + public long CardNumber { get; set; } + public int CardPin { get; set; } + public long AccountNumber { get; set; } + public string FullName { get; set; } + public decimal AccountBalance { get; set; } + public int TotalLogin { get; set; } + public bool IsLocked { get; set; } + + //public UserAccount( + // int id, long cardNumber, int cardPin, + // long accountNumber, string fullName, + // decimal accountBalance, int totalLogin, + // bool isLocked) + //{ + // Id = id; + // CardNumber = cardNumber; + // CardPin = cardPin; + // AccountNumber = accountNumber; + // FullName = fullName; + // AccountBalance = accountBalance; + // TotalLogin = totalLogin; + // IsLocked = isLocked; + + //} + + public override string ToString() + { + return "Id," + "CardNumber," + "CardPin," + "AccountNumber," + + "FullName," + "AccountBalance," + "TotalLogin," + "IsLocked,"; + } + + + } +} diff --git a/Boluwatife/StageTwoTask/BankProject/Domain/Enums/BankAppMenu.cs b/Boluwatife/StageTwoTask/BankProject/Domain/Enums/BankAppMenu.cs new file mode 100644 index 0000000..1c145e7 --- /dev/null +++ b/Boluwatife/StageTwoTask/BankProject/Domain/Enums/BankAppMenu.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BankProject.Domain.Enums +{ + public enum BankAppMenu + { + CheckBalance = 1, + PlaceDeposit, + MakeWithdrawal, + InternalTransfer, + ViewTransaction, + Logout + } +} diff --git a/Boluwatife/StageTwoTask/BankProject/Domain/Enums/OnBoarding.cs b/Boluwatife/StageTwoTask/BankProject/Domain/Enums/OnBoarding.cs new file mode 100644 index 0000000..101682b --- /dev/null +++ b/Boluwatife/StageTwoTask/BankProject/Domain/Enums/OnBoarding.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BankProject.Domain.Enums +{ + public enum OnBoarding + { + Register = 1, + Login + } +} diff --git a/Boluwatife/StageTwoTask/BankProject/Domain/Enums/TransactionType.cs b/Boluwatife/StageTwoTask/BankProject/Domain/Enums/TransactionType.cs new file mode 100644 index 0000000..908ef15 --- /dev/null +++ b/Boluwatife/StageTwoTask/BankProject/Domain/Enums/TransactionType.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BankProject.Domain.Enums +{ + public enum TransactionType + { + Deposit, + Withdrawal, + Transfer, + + } +} diff --git a/Boluwatife/StageTwoTask/BankProject/Program.cs b/Boluwatife/StageTwoTask/BankProject/Program.cs new file mode 100644 index 0000000..2bb7618 --- /dev/null +++ b/Boluwatife/StageTwoTask/BankProject/Program.cs @@ -0,0 +1,53 @@ +// See https://aka.ms/new-console-template for more information + +using BankProject.AppServices; +using BankProject.Display; +using System.Globalization; +using System.Text; + + + +UserServices userServices = new UserServices(); +userServices.InitializeData(); +//userServices.Run(); +//userServices.Regiser(); +userServices.OnBoard(); + + + + + + +//decimal val = 1278.112m; + + +//CultureInfo.DefaultThreadCurrentCulture = new CultureInfo("en-US"); +//Console.WriteLine($"{val}"); +//var culture = CultureInfo.CreateSpecificCulture("en-US"); +//var culture2 = new CultureInfo("en-US"); + +//string numberAsString = val.ToString("# #####.###", culture); +//string numberAsString2 = val.ToString("# #####.###", culture2); +//Console.WriteLine(numberAsString); +//Console.WriteLine(numberAsString2); + +//var culture = CultureInfo.CreateSpecificCulture("en-US"); +//var culture = CultureInfo.CreateSpecificCulture("en-NG"); +//Console.OutputEncoding = Encoding.Unicode; +//var culture = CultureInfo.CreateSpecificCulture("yo-NG"); +////decimal number = 1_500_000.50m; +//decimal number = 1500000.50m; + +//string numberString = number.ToString("C", CultureInfo.InvariantCulture); +////string numberString = number.ToString("C"); + +//string numberStringTwo = number.ToString("C0", culture); +//Console.WriteLine(numberString); +//Console.WriteLine(numberStringTwo); + + + + + + + diff --git a/Boluwatife/StageTwoTask/BankProject/Test.txt b/Boluwatife/StageTwoTask/BankProject/Test.txt new file mode 100644 index 0000000..0491dba --- /dev/null +++ b/Boluwatife/StageTwoTask/BankProject/Test.txt @@ -0,0 +1,7 @@ +1,Adebanjo Olaide,123456,321321,123123,5000.00,0,false +2,Folorunso Nene,456789,654654,456456 ,4000.00,0,false +3,test3,987654,987654, 987654,900000, 0,False +4,test4,234567,234567, 234567,700000, 0,False +5,test5,456789,456789, 456789,900000, 0,False +6,test6,345678,345678, 345678,90000, 0,False +7,test7,234567,234567, 234567,800000, 0,False diff --git a/Boluwatife/StageTwoTask/BankProject/Text1.txt b/Boluwatife/StageTwoTask/BankProject/Text1.txt new file mode 100644 index 0000000..0fb7aa6 --- /dev/null +++ b/Boluwatife/StageTwoTask/BankProject/Text1.txt @@ -0,0 +1,8 @@ +1 +qwer +12345 +12345 +0 +80000 +1 +False diff --git a/StageTwoTask/BankProject.sln b/StageTwoTask/BankProject.sln new file mode 100644 index 0000000..cecb6d6 --- /dev/null +++ b/StageTwoTask/BankProject.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.32014.148 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BankProject", "BankProject\BankProject.csproj", "{16C39874-DEFF-4271-9CE0-336111B0F833}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {16C39874-DEFF-4271-9CE0-336111B0F833}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {16C39874-DEFF-4271-9CE0-336111B0F833}.Debug|Any CPU.Build.0 = Debug|Any CPU + {16C39874-DEFF-4271-9CE0-336111B0F833}.Release|Any CPU.ActiveCfg = Release|Any CPU + {16C39874-DEFF-4271-9CE0-336111B0F833}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {123C7F3B-1B1C-48B0-9654-68ABF2074ED3} + EndGlobalSection +EndGlobal diff --git a/StageTwoTask/BankProject/AppServices/ITransaction.cs b/StageTwoTask/BankProject/AppServices/ITransaction.cs new file mode 100644 index 0000000..f233b6f --- /dev/null +++ b/StageTwoTask/BankProject/AppServices/ITransaction.cs @@ -0,0 +1,17 @@ +using BankProject.Domain.Enums; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BankProject.AppServices +{ + public interface ITransaction + { + void InsertTransaction(long _userBankAccountId, TransactionType _tranType, decimal _tranAmount, string _desc); + void ViewTransaction(); + + + } +} diff --git a/StageTwoTask/BankProject/AppServices/IUserAccountActions.cs b/StageTwoTask/BankProject/AppServices/IUserAccountActions.cs new file mode 100644 index 0000000..3ce5ad2 --- /dev/null +++ b/StageTwoTask/BankProject/AppServices/IUserAccountActions.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BankProject.AppServices +{ + public interface IUserAccountActions + { + void CheckBalance(); + void PlaceDeposit(); + void MakeWithDrawal(); + + } +} diff --git a/StageTwoTask/BankProject/AppServices/IUserLogin.cs b/StageTwoTask/BankProject/AppServices/IUserLogin.cs new file mode 100644 index 0000000..8d4d5fe --- /dev/null +++ b/StageTwoTask/BankProject/AppServices/IUserLogin.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BankProject.AppServices +{ + public interface IUserLogin + { + void CheckUserCardNumAndPassword(); + } +} diff --git a/StageTwoTask/BankProject/AppServices/UserServices.cs b/StageTwoTask/BankProject/AppServices/UserServices.cs new file mode 100644 index 0000000..f3c7df4 --- /dev/null +++ b/StageTwoTask/BankProject/AppServices/UserServices.cs @@ -0,0 +1,507 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using BankProject.Display; +using BankProject.Domain.Enitities; +using BankProject.Domain.Enums; +using ConsoleTables; +using Newtonsoft.Json; + +namespace BankProject.AppServices +{ + public class UserServices : IUserLogin, IUserAccountActions, ITransaction + { + // private List userAccountList; + private List userAccountList; + private UserAccount selectedAccount; + private List _ListOfTransactions; + + private const decimal minimumKeptAmount = 500; + + private readonly AppScreen screen; + + public UserServices() + { + screen = new AppScreen(); + userAccountList = new List(); + } + + + + public void OnBoard() + { + Console.WriteLine("Do you have an account, if NO enter 1 to REGISTER if YES enter 2 to LOGIN..."); + + switch (Validator.Convert("an option:")) + { + case (int)OnBoarding.Register: + Regiser(); + break; + case (int)OnBoarding.Login: + Run(); + break; + default: + Utility.PrintMessage("Invalid Options..", false); + break; + } + + + } + + public void Run() + { + AppScreen.Welcome(); + + CheckUserCardNumAndPassword(); + + AppScreen.WelcomeCustomer(selectedAccount.FullName); + while (true) + { + AppScreen.DisplaayAppMenu(); + + ProcessMenuoption(); + } + + } + + + public void Regiser() + { + AddNewMember(); + InitializeData(); + Run(); + } + + + public void AddNewMember() + { + string filePath = @"C:\Users\USER\Desktop\Project\BankProject\BankProject\Test.txt"; + List lines = File.ReadAllLines(filePath).ToList(); + List UserAccountList = new List(); + + int id; + string fullName; + long accountNumber; + long cardNumber; + int cardPin; + decimal accountBalance; + int totalLogin; + bool isLocked; + + Console.WriteLine("Kindly fill in the following details"); + Console.WriteLine(""); + Console.WriteLine("Kindly fill in your Id: "); + id = Convert.ToInt32(Console.ReadLine()); + Console.WriteLine("Kindly fill in your fullname: "); + fullName = Console.ReadLine(); + Console.WriteLine("Kindly fill in your accountNumber: "); + accountNumber = long.Parse(Console.ReadLine()); + Console.WriteLine("Kindly fill in your Card Number: "); + cardNumber = long.Parse(Console.ReadLine()); + Console.WriteLine("fill in yur card pin:"); + cardPin = Convert.ToInt32(Console.ReadLine()); + Console.WriteLine("fill you your first deposite: "); + accountBalance = long.Parse(Console.ReadLine()); + Console.WriteLine("fill in you total login as 0"); + totalLogin = Convert.ToInt32(Console.ReadLine()); + Console.WriteLine("locked access count: "); + isLocked = bool.Parse(Console.ReadLine()); + + UserAccountList.Add(new UserAccount + { + Id = id, + FullName = fullName, + AccountNumber = accountNumber, + CardNumber = cardNumber, + CardPin = cardPin, + AccountBalance = accountBalance, + TotalLogin = totalLogin, + IsLocked = isLocked + }); + + List output = new List(); + + foreach (var userAccount in UserAccountList) + { + output.Add($"{userAccount.Id},{userAccount.FullName},{userAccount.AccountNumber}," + + $"{userAccount.CardNumber}, {userAccount.CardPin}," + + $"{userAccount.AccountBalance}, {userAccount.TotalLogin}," + + $"{userAccount.IsLocked}"); + } + Console.WriteLine("Writting to text file"); + + File.AppendAllLines(filePath, output); + + // File.WriteAllLines(filePath, output); + + Console.WriteLine("All entries"); + + Console.WriteLine("done....."); + + } + + + public void InitializeData() + { + string filePath = @"C:\Users\USER\Desktop\Project\BankProject\BankProject\Test.txt"; + List UserAccountList = new List(); + List lines = File.ReadAllLines(filePath).ToList(); + foreach (string line in lines) + { + string[] entries = line.Split(','); + UserAccount userAccount = new UserAccount(); + + userAccount.Id = int.Parse(entries[0]); + userAccount.FullName = entries[1]; + userAccount.AccountNumber = long.Parse(entries[2]); + userAccount.CardNumber = long.Parse(entries[3]); + userAccount.CardPin = Int32.Parse(entries[4]); + userAccount.AccountBalance = Convert.ToDecimal(entries[5]); + userAccount.TotalLogin = int.Parse(entries[6]); + userAccount.IsLocked = bool.Parse(entries[7]); + + userAccountList.Add(userAccount); + } + +//1,Adebanjo Olaide,123456,321321,123123,5000.00,0,false +//2,Folorunso Nene,456789,654654,456456 ,4000.00,0,false +//3,Olatunji Money,987654,987987,789789,3000.00,1,true + + // userAccountList = new List + //{ + // new UserAccount{Id = 1, FullName = "Adebanjo Olaide", AccountNumber = 123456, CardNumber = 321321, CardPin = 123123, AccountBalance = 5000.00m, IsLocked=false}, + // new UserAccount{Id = 2, FullName = "Folorunso Nene", AccountNumber = 456789, CardNumber = 654654, CardPin = 456456 , AccountBalance = 4000.00m, IsLocked=false}, + // new UserAccount{Id = 3, FullName = "Olatunji Money", AccountNumber = 987654, CardNumber = 987987, CardPin = 789789, AccountBalance = 3000.00m, IsLocked=true}, + // }; + _ListOfTransactions = new List(); + + } + + public void CheckUserCardNumAndPassword() + { + int count = 0; + bool isCorrectLogin = false; + while (isCorrectLogin == false) + { + UserAccount inputAccount = AppScreen.UserLoginForm(); + AppScreen.LoginProgress(); + + + /// + //if + + //// + foreach (UserAccount account in userAccountList) + { + count++; + selectedAccount = account; + if (inputAccount.CardNumber.Equals(selectedAccount.CardNumber)) + { + selectedAccount.TotalLogin++; + + if (inputAccount.CardPin.Equals(selectedAccount.CardPin)) + { + selectedAccount = account; + + if (selectedAccount.IsLocked || selectedAccount.TotalLogin > 3) + { + AppScreen.PrintLockScreen(); + } + else + { + selectedAccount.TotalLogin = 0; + isCorrectLogin = true; + break; + } + } + } + if (count < userAccountList.Count) + { + continue; + } + if (count >= userAccountList.Count) + { + if (isCorrectLogin == false) + { + Utility.PrintMessage("\nInvalid card number or PIN.", false); + selectedAccount.IsLocked = selectedAccount.TotalLogin == 3; + if (selectedAccount.IsLocked) + { + AppScreen.PrintLockScreen(); + } + } + } + ///if not end of the list do not go futher untill you check the whole list + //if (isCorrectLogin == false) + //{ + // Utility.PrintMessage("\nInvalid card number or PIN.", false); + // selectedAccount.IsLocked = selectedAccount.TotalLogin == 3; + // if (selectedAccount.IsLocked) + // { + // AppScreen.PrintLockScreen(); + // } + //} + Console.Clear(); + } + } + + } + + private void ProcessMenuoption() + { + switch(Validator.Convert("an option:")) + { + case (int)BankAppMenu.CheckBalance: + CheckBalance(); + break; + case (int)BankAppMenu.PlaceDeposit: + PlaceDeposit(); + break; + case (int)BankAppMenu.MakeWithdrawal: + MakeWithDrawal(); + break; + case (int)BankAppMenu.InternalTransfer: + var internalTransfer = screen.InternalTransferForm(); + ProcessInternalTransfer(internalTransfer); + break; + case (int)BankAppMenu.ViewTransaction: + ViewTransaction(); + break; + case (int)BankAppMenu.Logout: + AppScreen.LogOutProgress(); + Utility.PrintMessage("You have successfully logged out.", true); + Run(); + break; + default: + Utility.PrintMessage("Invalid Options..", false); + break; + } + } + + //check balance + public void CheckBalance() + { + Utility.PrintMessage($"Your account balance is: {Utility.FormatAmount(selectedAccount.AccountBalance)}", true); + } + + public void PlaceDeposit() + { + Console.WriteLine("\nOnly multiple of 500 and 1000 naira allowed.\n"); + + var transaction_amt = Validator.Convert($"amount {AppScreen.cur}"); + + //simulate counting + Console.WriteLine("\nChecking and Counting bank notes."); + Utility.PrintDotAnimation(); + + Console.WriteLine(""); + + if(transaction_amt <= 0) + { + Utility.PrintMessage("Amount needs to be greater than 0", false); + return; + } + if (transaction_amt % 500 != 0) + { + Utility.PrintMessage($"Enter deposit amount of mutiple of 500 or 1000. Tray again.", false); + return; + } + + if (PreviewBankNotesCount(transaction_amt) == false) + { + Utility.PrintMessage($"You have cancalled your action.", false); + return; + } + + //bind transaction detatails to the transaction object + InsertTransaction(selectedAccount.Id, TransactionType.Deposit, transaction_amt, ""); + + //Update Account balance + selectedAccount.AccountBalance += transaction_amt; + + //print success message to the screen + Utility.PrintMessage($"Your deposit of {Utility.FormatAmount(transaction_amt)} was successful", true); + + + } + + + //Make withdrawal method + public void MakeWithDrawal() + { + var transaction_amt = 0; + int selectedAmount = AppScreen.SelectAmonunt(); + + if (selectedAmount == -1) + { + //reccuive calling of the same method. + MakeWithDrawal(); + return; + } + else if (selectedAmount != 0) + { + transaction_amt = selectedAmount; + } + else + { + //if user select 0 + transaction_amt = Validator.Convert($"amount{AppScreen.cur}"); + } + + //input validation + if(transaction_amt <= 0) + { + Utility.PrintMessage("Amount must be greater than zero.", false); + return; + } + if (transaction_amt % 500 != 0) + { + Utility.PrintMessage("You can only Withdraw amount in multiples of 5000 or 1000", false); + return; + } + + //Logic validations + if(transaction_amt > selectedAccount.AccountBalance) + { + Utility.PrintMessage($"Withdralal failed. Your balance is too low {Utility.FormatAmount(transaction_amt)}", false); + return; + } + + if ((selectedAccount.AccountBalance - transaction_amt) < minimumKeptAmount) + { + Utility.PrintMessage($"Withdrawal failed. Your account needs to have " + + $"minimum {Utility.FormatAmount(minimumKeptAmount)}", false); + return; + } + + //Bind withdrawal details to transaction object + InsertTransaction(selectedAccount.Id, TransactionType.Withdrawal, -transaction_amt, ""); + //update account balance + selectedAccount.AccountBalance -= transaction_amt; + //success message + Utility.PrintMessage($"You have successfully withdrawn " + + $"{Utility.FormatAmount(transaction_amt)}.", true); + + } + + + private bool PreviewBankNotesCount(int amount) + { + int thousandNotesCount = amount / 1000; + int fiveHundredNotesCount = (amount % 1000) / 500; + + Console.WriteLine("\nSummary"); + Console.WriteLine("-------"); + Console.WriteLine($"{AppScreen.cur}1000 X {thousandNotesCount} = {1000 * thousandNotesCount}"); + Console.WriteLine($"{AppScreen.cur}500 X {fiveHundredNotesCount} = {500 * fiveHundredNotesCount}"); + Console.WriteLine($"Total amount: {Utility.FormatAmount(amount)}\n\n"); + + int opt = Validator.Convert("1 to confirm"); + return opt.Equals(1); + + } + + public void InsertTransaction(long _userBankAccountId, TransactionType _tranType, decimal _tranAmount, string _desc) + { + //Create a new Transaction object + var transaction = new Transaction() + { + TransactionId = Utility.GetTransactionId(), + UserBankAccountId = _userBankAccountId, + TransactionDate = DateTime.Now, + TransactionType = _tranType, + TransactionAmount = _tranAmount, + Descriprion = _desc + }; + + _ListOfTransactions.Add(transaction); + } + + public void ViewTransaction() + { + var filteredTransactionList = _ListOfTransactions.Where(t => t.UserBankAccountId == selectedAccount.Id).ToList(); + //check if there's a transaction + if (filteredTransactionList.Count <= 0) + { + Utility.PrintMessage("You have no transaction yet.", true); + } + else + { + //Install a console table to draw the table. + var table = new ConsoleTable("Id", "Transaction Date", "Type", "Descriptions", "Amount " + AppScreen.cur); + foreach (var tran in filteredTransactionList) + { + table.AddRow(tran.TransactionId, tran.TransactionDate, tran.TransactionType, tran.Descriprion, tran.TransactionAmount); + } + table.Options.EnableCount = false; + table.Write(); + Utility.PrintMessage($"You have {filteredTransactionList.Count} transaction(s)", true); + } + + } + + private void ProcessInternalTransfer(InternalTransfer internalTransfer) + { + if (internalTransfer.TransferAmount <= 0) + { + Utility.PrintMessage("Amount needs to be more than 0. Try again", false); + return; + } + + //check sender's account balance + if(internalTransfer.TransferAmount > selectedAccount.AccountBalance) + { + Utility.PrintMessage($"Transfered failed, Insufficeint funds{Utility.FormatAmount(internalTransfer.TransferAmount)}", false); + return; + } + + //check the minimum kept amount + if ((selectedAccount.AccountBalance - internalTransfer.TransferAmount) < minimumKeptAmount) + { + Utility.PrintMessage($"Transfer faile. Your account needs to have minimum" + + $" {Utility.FormatAmount(minimumKeptAmount)}", false); + return; + } + + //check reciever's account number is valid *************************************************************** + var selectedBankAccountReciever = (from userAcc in userAccountList + where userAcc.AccountNumber == internalTransfer.ReciepeintBankAccountNumber + select userAcc).FirstOrDefault(); + if (selectedBankAccountReciever == null) + { + Utility.PrintMessage("Transfer failed. Recieber bank account number is invalid.", false); + return; + } + //check receiver's name + if (selectedBankAccountReciever.FullName != internalTransfer.RecipientBankAccountName) + { + Utility.PrintMessage("Transfer Failed. Recipient's bank account name does not match.", false); + return; + } + + //add transaction to transactions record- sender + InsertTransaction(selectedAccount.Id, TransactionType.Transfer, -internalTransfer.TransferAmount, "Transfered " + + $"to {selectedBankAccountReciever.AccountNumber} ({selectedBankAccountReciever.FullName})"); + //update sender's account balance + selectedAccount.AccountBalance -= internalTransfer.TransferAmount; + + //add transaction record-reciever + InsertTransaction(selectedBankAccountReciever.Id, TransactionType.Transfer, internalTransfer.TransferAmount, "Transfered from " + + $"{selectedAccount.AccountNumber}({selectedAccount.FullName})"); + //update reciever's account balance + selectedBankAccountReciever.AccountBalance += internalTransfer.TransferAmount; + //print success message + Utility.PrintMessage($"You have successfully transfered" + + $" {Utility.FormatAmount(internalTransfer.TransferAmount)} to " + + $"{internalTransfer.RecipientBankAccountName}", true); + + } + } + +} + + + + diff --git a/StageTwoTask/BankProject/BankProject.csproj b/StageTwoTask/BankProject/BankProject.csproj new file mode 100644 index 0000000..b0d0642 --- /dev/null +++ b/StageTwoTask/BankProject/BankProject.csproj @@ -0,0 +1,15 @@ + + + + Exe + net6.0 + enable + enable + + + + + + + + diff --git a/StageTwoTask/BankProject/Display/AppScreen.cs b/StageTwoTask/BankProject/Display/AppScreen.cs new file mode 100644 index 0000000..6420d63 --- /dev/null +++ b/StageTwoTask/BankProject/Display/AppScreen.cs @@ -0,0 +1,148 @@ +using BankProject.Domain.Enitities; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BankProject.Display +{ + public class AppScreen + { + internal const string cur = "N "; + + public static void Welcome() + { + //clears the console Screen + Console.Clear(); + //Sets the title of the console window + Console.Title = "My Bank APP"; + + //set the Text color to white + Console.ForegroundColor = ConsoleColor.White; + + //Welcome message + Console.WriteLine("\n\n -------------Welcome to My Bank APP-------------\n\n"); + + //Prompt the user to insert ATM + Console.WriteLine("Please Enter your Bank Card Number"); + + Console.WriteLine("Note: We don't accept physical card"); + + Utility.PressEnterToContinue(); + + } + + internal static UserAccount UserLoginForm() + { + UserAccount tempUserAccount = new UserAccount(); + + tempUserAccount.CardNumber = Validator.Convert("Your Bank Account card number..."); + + //Hidden input to mask pin. + tempUserAccount.CardPin = Convert.ToInt32(Utility.GetSecretInput("Enter your Card PIN")); + + return tempUserAccount; + } + + internal static void LoginProgress() + { + Console.WriteLine("\nChecking card number and Pin....."); + + Utility.PrintDotAnimation(); + + } + + internal static void PrintLockScreen() + { + Console.Clear(); + Utility.PrintMessage("Your account has been locked", true); + + Utility.PressEnterToContinue(); + Environment.Exit(1); + } + + internal static void WelcomeCustomer(string fullName) + { + Console.WriteLine($"Welcome back,{fullName}."); + } + + internal static void DisplaayAppMenu() + { + Console.Clear(); + Console.WriteLine("---------My Bank APP Menu----------"); + Console.WriteLine(": "); + Console.WriteLine("1. Account Balance :"); + Console.WriteLine("2. Cash Deposit :"); + Console.WriteLine("3. Withdrawal :"); + Console.WriteLine("4. Transfer :"); + Console.WriteLine("5. Transactions :"); + Console.WriteLine("6. Logout :"); + } + + internal static void LogOutProgress() + { + Console.WriteLine("Thank you for using My Bank APP..."); + Utility.PrintDotAnimation(); + Console.Clear(); + } + + internal static int SelectAmonunt() + { + Console.WriteLine(""); + Console.WriteLine(":1.{0}500 5.{0}10,000", cur); + Console.WriteLine(":2.{0}1000 6.{0}15,000", cur); + Console.WriteLine(":3.{0}2000 7.{0}20,000", cur); + Console.WriteLine(":4.{0}5000 8.{0}40,000", cur); + Console.WriteLine(":0.Other"); + Console.WriteLine(""); + + int selectedAmount = Validator.Convert("option:"); + switch (selectedAmount) + { + case 1: + return 500; + break; + case 2: + return 1000; + break; + case 3: + return 2000; + break; + case 4: + return 5000; + break; + case 5: + return 10000; + break; + case 6: + return 15000; + break; + case 7: + return 20000; + break; + case 8: + return 40000; + break; + case 0: + return 0; + break; + default: + Utility.PrintMessage("Invalid input. try again", false); + return -1; + break; + } + } + + + internal InternalTransfer InternalTransferForm() + { + var internalTransfer = new InternalTransfer(); + internalTransfer.ReciepeintBankAccountNumber = Validator.Convert("recipient's account number:"); + internalTransfer.TransferAmount = Validator.Convert($"amount {cur}"); + internalTransfer.RecipientBankAccountName = Utility.GetUserInput("recipient's name:"); + return internalTransfer; + } + + } +} diff --git a/StageTwoTask/BankProject/Display/Utility.cs b/StageTwoTask/BankProject/Display/Utility.cs new file mode 100644 index 0000000..fd2b4c7 --- /dev/null +++ b/StageTwoTask/BankProject/Display/Utility.cs @@ -0,0 +1,114 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BankProject.Display +{ + public static class Utility + { + private static long tranId; + // private static CultureInfo culture = new CultureInfo("en-US"); + + + public static long GetTransactionId() + { + return ++tranId; + } + + + public static string GetSecretInput(string prompt) + { + bool isPrompt = true; + string asterics = ""; + + StringBuilder input = new StringBuilder(); + + while (true) + { + if(isPrompt) + Console.WriteLine(prompt); + + //once we promot the user for input, set it back to false + isPrompt = false; + ConsoleKeyInfo inputKey = Console.ReadKey(true); + + if (inputKey.Key == ConsoleKey.Enter) + { + if(input.Length == 6) + { + break; + } + else + { + PrintMessage("Please enter 6 digits..", false); + isPrompt = true; + input.Clear(); + continue; + } + } + + if (inputKey.Key == ConsoleKey.Backspace && input.Length > 0) + { + input.Remove(input.Length - 1, 1); + } else if(inputKey.Key != ConsoleKey.Backspace) + { + input.Append(inputKey.KeyChar); + Console.Write(asterics + "*"); + } + } + return input.ToString(); + } + + + public static void PrintMessage(string msg, bool success) + { + if (success) + { + Console.ForegroundColor = ConsoleColor.Green; + } + else + { + Console.ForegroundColor = ConsoleColor.Red; + } + Console.WriteLine(msg); + Console.ForegroundColor = ConsoleColor.White; + PressEnterToContinue(); + } + + public static string GetUserInput(string prompt) + { + Console.WriteLine($"Enter {prompt}"); + return Console.ReadLine(); + } + + public static void PrintDotAnimation(int timer = 10) + { + for (int i = 0; i < timer; i++) + { + Console.Write(".."); + Thread.Sleep(200); + } + Console.Clear(); + } + + public static void PressEnterToContinue() + { + Console.WriteLine("\n\nPress Enter to continue...\n"); + Console.ReadLine(); + } + + public static string FormatAmount(decimal amt) + { + Console.OutputEncoding = Encoding.Unicode; + //return string.Format(culture, "{0:C2}", amt); + //var culture = CultureInfo.CreateSpecificCulture("en-US"); + var culture = CultureInfo.CreateSpecificCulture("yo-NG"); + string decimalToString = amt.ToString("C", culture); + return decimalToString; + + } + } +} diff --git a/StageTwoTask/BankProject/Display/Validator.cs b/StageTwoTask/BankProject/Display/Validator.cs new file mode 100644 index 0000000..2b2d8f5 --- /dev/null +++ b/StageTwoTask/BankProject/Display/Validator.cs @@ -0,0 +1,41 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BankProject.Display +{ + public static class Validator + { + public static T Convert(string prompt) + { + bool valid = false; + string userInput; + //while true(untill a valid input code runs continously) + while (!valid) + { + userInput = Utility.GetUserInput(prompt); + + try + { + var converter = TypeDescriptor.GetConverter(typeof(T)); + if (converter != null) + { + return (T)converter.ConvertFromString(userInput)!; + } + else + { + return default!; + } + } + catch + { + Utility.PrintMessage("Invalid input.Try again!!!.", false); + } + } + return default!; + } + } +} diff --git a/StageTwoTask/BankProject/Domain/Enitities/InternalTransfer.cs b/StageTwoTask/BankProject/Domain/Enitities/InternalTransfer.cs new file mode 100644 index 0000000..3544dac --- /dev/null +++ b/StageTwoTask/BankProject/Domain/Enitities/InternalTransfer.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BankProject.Domain.Enitities +{ + public class InternalTransfer + { + public decimal TransferAmount { get; set; } + public long ReciepeintBankAccountNumber { get; set; } + public string RecipientBankAccountName { get; set; } + } +} diff --git a/StageTwoTask/BankProject/Domain/Enitities/Transaction.cs b/StageTwoTask/BankProject/Domain/Enitities/Transaction.cs new file mode 100644 index 0000000..7313ae6 --- /dev/null +++ b/StageTwoTask/BankProject/Domain/Enitities/Transaction.cs @@ -0,0 +1,19 @@ +using BankProject.Domain.Enums; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BankProject.Domain.Enitities +{ + public class Transaction + { + public long TransactionId { get; set; } + public long UserBankAccountId { get; set; } + public DateTime TransactionDate { get; set; } + public TransactionType TransactionType { get; set; } + public string Descriprion { get; set; } + public Decimal TransactionAmount { get; set; } + } +} diff --git a/StageTwoTask/BankProject/Domain/Enitities/UserAccount.cs b/StageTwoTask/BankProject/Domain/Enitities/UserAccount.cs new file mode 100644 index 0000000..77c19a5 --- /dev/null +++ b/StageTwoTask/BankProject/Domain/Enitities/UserAccount.cs @@ -0,0 +1,45 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BankProject.Domain.Enitities +{ + public class UserAccount + { + public int Id { get; set; } + public long CardNumber { get; set; } + public int CardPin { get; set; } + public long AccountNumber { get; set; } + public string FullName { get; set; } + public decimal AccountBalance { get; set; } + public int TotalLogin { get; set; } + public bool IsLocked { get; set; } + + //public UserAccount( + // int id, long cardNumber, int cardPin, + // long accountNumber, string fullName, + // decimal accountBalance, int totalLogin, + // bool isLocked) + //{ + // Id = id; + // CardNumber = cardNumber; + // CardPin = cardPin; + // AccountNumber = accountNumber; + // FullName = fullName; + // AccountBalance = accountBalance; + // TotalLogin = totalLogin; + // IsLocked = isLocked; + + //} + + public override string ToString() + { + return "Id," + "CardNumber," + "CardPin," + "AccountNumber," + + "FullName," + "AccountBalance," + "TotalLogin," + "IsLocked,"; + } + + + } +} diff --git a/StageTwoTask/BankProject/Domain/Enums/BankAppMenu.cs b/StageTwoTask/BankProject/Domain/Enums/BankAppMenu.cs new file mode 100644 index 0000000..1c145e7 --- /dev/null +++ b/StageTwoTask/BankProject/Domain/Enums/BankAppMenu.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BankProject.Domain.Enums +{ + public enum BankAppMenu + { + CheckBalance = 1, + PlaceDeposit, + MakeWithdrawal, + InternalTransfer, + ViewTransaction, + Logout + } +} diff --git a/StageTwoTask/BankProject/Domain/Enums/OnBoarding.cs b/StageTwoTask/BankProject/Domain/Enums/OnBoarding.cs new file mode 100644 index 0000000..101682b --- /dev/null +++ b/StageTwoTask/BankProject/Domain/Enums/OnBoarding.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BankProject.Domain.Enums +{ + public enum OnBoarding + { + Register = 1, + Login + } +} diff --git a/StageTwoTask/BankProject/Domain/Enums/TransactionType.cs b/StageTwoTask/BankProject/Domain/Enums/TransactionType.cs new file mode 100644 index 0000000..908ef15 --- /dev/null +++ b/StageTwoTask/BankProject/Domain/Enums/TransactionType.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BankProject.Domain.Enums +{ + public enum TransactionType + { + Deposit, + Withdrawal, + Transfer, + + } +} diff --git a/StageTwoTask/BankProject/Program.cs b/StageTwoTask/BankProject/Program.cs new file mode 100644 index 0000000..2bb7618 --- /dev/null +++ b/StageTwoTask/BankProject/Program.cs @@ -0,0 +1,53 @@ +// See https://aka.ms/new-console-template for more information + +using BankProject.AppServices; +using BankProject.Display; +using System.Globalization; +using System.Text; + + + +UserServices userServices = new UserServices(); +userServices.InitializeData(); +//userServices.Run(); +//userServices.Regiser(); +userServices.OnBoard(); + + + + + + +//decimal val = 1278.112m; + + +//CultureInfo.DefaultThreadCurrentCulture = new CultureInfo("en-US"); +//Console.WriteLine($"{val}"); +//var culture = CultureInfo.CreateSpecificCulture("en-US"); +//var culture2 = new CultureInfo("en-US"); + +//string numberAsString = val.ToString("# #####.###", culture); +//string numberAsString2 = val.ToString("# #####.###", culture2); +//Console.WriteLine(numberAsString); +//Console.WriteLine(numberAsString2); + +//var culture = CultureInfo.CreateSpecificCulture("en-US"); +//var culture = CultureInfo.CreateSpecificCulture("en-NG"); +//Console.OutputEncoding = Encoding.Unicode; +//var culture = CultureInfo.CreateSpecificCulture("yo-NG"); +////decimal number = 1_500_000.50m; +//decimal number = 1500000.50m; + +//string numberString = number.ToString("C", CultureInfo.InvariantCulture); +////string numberString = number.ToString("C"); + +//string numberStringTwo = number.ToString("C0", culture); +//Console.WriteLine(numberString); +//Console.WriteLine(numberStringTwo); + + + + + + + diff --git a/StageTwoTask/BankProject/Test.txt b/StageTwoTask/BankProject/Test.txt new file mode 100644 index 0000000..0491dba --- /dev/null +++ b/StageTwoTask/BankProject/Test.txt @@ -0,0 +1,7 @@ +1,Adebanjo Olaide,123456,321321,123123,5000.00,0,false +2,Folorunso Nene,456789,654654,456456 ,4000.00,0,false +3,test3,987654,987654, 987654,900000, 0,False +4,test4,234567,234567, 234567,700000, 0,False +5,test5,456789,456789, 456789,900000, 0,False +6,test6,345678,345678, 345678,90000, 0,False +7,test7,234567,234567, 234567,800000, 0,False diff --git a/StageTwoTask/BankProject/Text1.txt b/StageTwoTask/BankProject/Text1.txt new file mode 100644 index 0000000..0fb7aa6 --- /dev/null +++ b/StageTwoTask/BankProject/Text1.txt @@ -0,0 +1,8 @@ +1 +qwer +12345 +12345 +0 +80000 +1 +False