diff --git a/sav_bank/App.config b/sav_bank/App.config
new file mode 100644
index 0000000..7d84477
--- /dev/null
+++ b/sav_bank/App.config
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/sav_bank/Program.cs b/sav_bank/Program.cs
new file mode 100644
index 0000000..1d02048
--- /dev/null
+++ b/sav_bank/Program.cs
@@ -0,0 +1,20 @@
+using sav_bank.presentation;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace sav_bank
+{
+ internal class Program
+ {
+
+ private const string storageFile = "bank.txt";
+ static void Main(string[] args)
+ {
+ Console.WriteLine("Welcome to Sav Bank");
+ Presentaion.Present(storageFile);
+ }
+ }
+}
diff --git a/sav_bank/Properties/AssemblyInfo.cs b/sav_bank/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..cd04a92
--- /dev/null
+++ b/sav_bank/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("sav_bank")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("sav_bank")]
+[assembly: AssemblyCopyright("Copyright © 2023")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("04e34733-76c1-48c2-98b4-a267db477078")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/sav_bank/data/DataBase.cs b/sav_bank/data/DataBase.cs
new file mode 100644
index 0000000..a8ae138
--- /dev/null
+++ b/sav_bank/data/DataBase.cs
@@ -0,0 +1,99 @@
+using sav_bank.model;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text.Json;
+
+namespace sav_bank.data
+{
+ public class DataBase
+ {
+ public static bool AddData(Bank model, string fileName)
+ {
+ try
+ {
+ var currentData = GetData(fileName);
+ currentData.Add(model);
+
+ var options = new JsonSerializerOptions { WriteIndented = true };
+
+ string stringJson = JsonSerializer.Serialize(currentData, options: options);
+ File.WriteAllText(fileName, stringJson);
+ return true;
+ }
+ catch (System.Exception)
+ {
+
+ return false;
+ }
+
+
+ }
+
+ public static bool Update(Bank model, string fileName)
+ {
+ try
+ {
+ var currentData = GetData(fileName);
+
+ var index = currentData.IndexOf(model);
+ currentData[index] =model;
+
+ var options = new JsonSerializerOptions { WriteIndented = true };
+
+ string stringJson = JsonSerializer.Serialize(currentData, options: options);
+ File.WriteAllBytes(fileName, new byte[0]);
+ File.WriteAllText(fileName, stringJson);
+ return true;
+ }
+ catch (System.Exception)
+ {
+ return false;
+ }
+
+
+ }
+
+
+ public static List GetData(string fileName)
+ {
+
+ try
+ {
+ string jsonString = File.ReadAllText(fileName);
+ List bank = JsonSerializer.Deserialize>(jsonString);
+ if (bank != null)
+ {
+ return bank;
+ }
+
+ return new List();
+
+ }
+ catch (System.Exception)
+ {
+
+ return new List();
+ }
+
+ }
+
+ public static Bank GetDataByUserId(string userId, string fileName)
+ {
+
+ var currentData = GetData(fileName);
+ if (currentData.Any())
+ {
+ var userData = currentData.SingleOrDefault(x => x.UserName == userId);
+
+ return userData;
+ }
+ else
+ {
+
+ return null;
+ }
+ }
+ }
+}
diff --git a/sav_bank/model/AccountSummary.cs b/sav_bank/model/AccountSummary.cs
new file mode 100644
index 0000000..54e5efb
--- /dev/null
+++ b/sav_bank/model/AccountSummary.cs
@@ -0,0 +1,16 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace sav_bank.model
+{
+ public class AccountSummary
+ {
+ public string Date { get; set; }
+ public bool IsDeposit { get; set; }
+ public string Amount { get; set; }
+ public string CurrentBalance { get; set; }
+ }
+}
diff --git a/sav_bank/model/Bank.cs b/sav_bank/model/Bank.cs
new file mode 100644
index 0000000..9e0f6bb
--- /dev/null
+++ b/sav_bank/model/Bank.cs
@@ -0,0 +1,101 @@
+using sav_bank.utils;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Text.Json.Serialization;
+using System.Threading.Tasks;
+
+namespace sav_bank.model
+{
+ public class Bank : IEquatable
+ {
+ [JsonInclude]
+ public string UserId { get; private set; }
+ public string UserName { get; set; }
+ public string FirstName { get; set; }
+ public string LastName { get; set; }
+ public string Email { get; set; }
+ [JsonInclude]
+ public string AccountNumber { get; private set; }
+ public string Age { get; set; }
+ public string PhoneNumber { get; set; }
+ public byte[] PasswordHash { get; set; }
+ public byte[] PasswordSalt { get; set; }
+ [JsonInclude]
+ public decimal Balance { get; private set; }
+ public List AccountSummary { get; set; }
+ public Bank()
+ {
+
+ }
+
+ public Bank(string userName, string email, string phoneNumber, string firstName, string lastName, string age, byte[] passwordHash, byte[] passwordSalt)
+ {
+ UserId = PasswordHelper.GenerateUserId();
+ AccountNumber = PasswordHelper.GenerateAccountNumber();
+ UserName = userName;
+ Email = email;
+ Age = age;
+ FirstName = firstName;
+ LastName = lastName;
+ PhoneNumber = phoneNumber;
+ PasswordHash = passwordHash;
+ PasswordSalt = passwordSalt;
+ Balance = 0;
+ AccountSummary = new List();
+
+ }
+
+ public bool Equals(Bank other)
+ {
+ if (this.AccountNumber != other.AccountNumber) return false;
+ if (this.UserId != other.UserId) return false;
+
+
+ return true;
+ }
+
+ public decimal AddAcountBalance(decimal amount)
+ {
+ if(amount > 0)
+ {
+
+ this.Balance += amount;
+ AddSummary(amount.ToString(), true);
+ return this.Balance;
+ }
+ else
+ {
+ return -1;
+ }
+ }
+ public decimal Withdraw(decimal amount)
+ {
+ if (amount > 0 && this.Balance > 0 && this.Balance > amount)
+ {
+ this.Balance = this.Balance - amount;
+ AddSummary(amount.ToString(), false);
+ return this.Balance;
+ }
+ else
+ {
+ return -1;
+ }
+ }
+
+ private void AddSummary(string amount, bool isDeposit)
+ {
+ var summary = new AccountSummary()
+ {
+ Amount = amount,
+ Date = DateTime.Now.ToString(),
+ IsDeposit= isDeposit,
+ CurrentBalance = this.Balance.ToString(),
+
+ };
+
+ AccountSummary.Add(summary);
+ }
+ }
+}
diff --git a/sav_bank/model/Response.cs b/sav_bank/model/Response.cs
new file mode 100644
index 0000000..cfa60d6
--- /dev/null
+++ b/sav_bank/model/Response.cs
@@ -0,0 +1,15 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace sav_bank.model
+{
+ public class BankResponse
+ {
+ public string Code { get; set; }
+ public string Description { get; set; }
+ public T Data { get; set; }
+ }
+}
diff --git a/sav_bank/model/SignUpDtos.cs b/sav_bank/model/SignUpDtos.cs
new file mode 100644
index 0000000..437756f
--- /dev/null
+++ b/sav_bank/model/SignUpDtos.cs
@@ -0,0 +1,19 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace sav_bank
+{
+ public class SignUpDtos
+ {
+ public string UserName { get; set; }
+ public string FirstName { get; set; }
+ public string LastName { get; set; }
+ public string Email { get; set; }
+ public string Age { get; set; }
+ public string PhoneNumber { get; set; }
+ public string Password { get; set; }
+ }
+}
diff --git a/sav_bank/packages.config b/sav_bank/packages.config
new file mode 100644
index 0000000..b440707
--- /dev/null
+++ b/sav_bank/packages.config
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/sav_bank/presentation/AccountPresentation.cs b/sav_bank/presentation/AccountPresentation.cs
new file mode 100644
index 0000000..2893775
--- /dev/null
+++ b/sav_bank/presentation/AccountPresentation.cs
@@ -0,0 +1,111 @@
+using sav_bank.model;
+using sav_bank.service;
+using sav_bank.utils;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace sav_bank.presentation
+{
+ public class AccountPresentation
+ {
+
+ private static void WriteSumarry(AccountSummary summary)
+ {
+ Console.WriteLine("Deposit Date: {0}\n{1} Amount: N{2}\nCurrent balance: N{3}", summary.Date, summary.IsDeposit ? "Deposit" : "Withdrawal", summary.Amount, summary.CurrentBalance);
+ SymbolWriter.WriteSymbol(symbol: "$");
+ }
+ public static void PresentAccount(in Bank user, string fileName) {
+ Console.WriteLine("Bank with us:");
+ Console.WriteLine("Press 1 to VIEW ACCOUNT SUMMARY");
+ Console.WriteLine("Press 2 to VIEW BALANCE");
+ Console.WriteLine("Press 3 to DEPOSIT");
+ Console.WriteLine("Press 4 to WITHDRAW");
+
+ Console.Write(">>>>> ");
+ var action = int.Parse(Console.ReadLine());
+
+ switch (action)
+ {
+ case 1:
+ var accountSummary = AccountService.GetAccountSummary(user.UserName, fileName);
+ if (accountSummary.Code.Equals("00"))
+ {
+ SymbolWriter.WriteSymbol();
+
+ foreach (var summary in accountSummary.Data)
+ WriteSumarry(summary);
+ SymbolWriter.WriteSymbol();
+ }
+ else
+ {
+ Console.WriteLine(accountSummary.Description);
+ }
+ break;
+ case 2:
+ var accountBalance = AccountService.GetAccountBalance(user.UserName, fileName);
+ if (accountBalance.Code.Equals("00"))
+ {
+ Console.WriteLine("Account Balance: N{0}", accountBalance.Data);
+ }
+ else
+ {
+ Console.WriteLine(accountBalance.Description);
+ }
+ break;
+ case 3:
+ var deposit = AccountService.DepositAccount(user.UserName, fileName);
+ if (deposit.Code.Equals("00"))
+ {
+ Console.WriteLine("Account Balance: N{0}", deposit.Data);
+ }
+ else
+ {
+ Console.WriteLine(deposit.Description);
+ }
+ break;
+ case 4:
+ var withdraw = AccountService.Withdraw(user.UserName, fileName);
+ if (withdraw.Code.Equals("00"))
+ {
+ Console.WriteLine("Account Balance: N{0}", withdraw.Data);
+ }
+ else
+ {
+ Console.WriteLine(withdraw.Description);
+ }
+ break;
+ default:
+ Console.WriteLine("Input the correct value");
+ break;
+ }
+
+ Console.WriteLine("Do you want to perform another transaction");
+ Console.WriteLine("............ Press 1 to continue");
+ Console.WriteLine("............ Press 2 to quit");
+ Console.Write(">>>>> ");
+ var anotherAction = int.Parse(Console.ReadLine());
+
+ while (anotherAction > 2)
+ {
+ Console.WriteLine("Please input the correct value.");
+ Console.Write(">>>>> ");
+ anotherAction = int.Parse(Console.ReadLine());
+ }
+
+ if (anotherAction == 1)
+ {
+ PresentAccount(in user, fileName);
+ }
+ else if (anotherAction == 2)
+ {
+ Console.WriteLine("Thank you for banking with us");
+
+ }
+
+ SymbolWriter.WriteSymbol();
+ }
+ }
+}
diff --git a/sav_bank/presentation/LoginPresentation.cs b/sav_bank/presentation/LoginPresentation.cs
new file mode 100644
index 0000000..1bc4f62
--- /dev/null
+++ b/sav_bank/presentation/LoginPresentation.cs
@@ -0,0 +1,54 @@
+using sav_bank.model;
+using sav_bank.service;
+using sav_bank.utils;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace sav_bank.presentation
+{
+ public class LoginPresentation
+ {
+ public static Bank PresentLogin(string fileName)
+
+ {
+ int attempt = 3;
+ string userName;
+ string password;
+ Console.WriteLine("To Login Enter your user name and Password");
+ while(attempt != 0 )
+ {
+
+ Console.Write("Username: ");
+ userName = Console.ReadLine();
+ Console.Write("Password: ");
+ password = Console.ReadLine();
+ var login = LoginService.UserLogin(userName, password, fileName);
+ if (login.Code.Equals("00"))
+ {
+
+
+ SymbolWriter.WriteSymbol();
+ Console.WriteLine(login.Data.UserName + " logged in successfully");
+ SymbolWriter.WriteSymbol();
+
+ return login.Data;
+
+ }
+ else
+ {
+
+ attempt--;
+ Console.WriteLine("{0} , You have {1} attempts left",login.Description, attempt);
+ }
+ }
+ if(attempt == 0 )
+ Console.WriteLine("You attempted more than 3 times account locked ");
+ Console.ReadKey();
+
+ return null;
+ }
+ }
+}
diff --git a/sav_bank/presentation/Presentaion.cs b/sav_bank/presentation/Presentaion.cs
new file mode 100644
index 0000000..556f8ec
--- /dev/null
+++ b/sav_bank/presentation/Presentaion.cs
@@ -0,0 +1,56 @@
+using sav_bank.model;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace sav_bank.presentation
+{
+ public class Presentaion
+ {
+ public static void Present(string fileName)
+ {
+ string input;
+
+ while (true) {
+ Console.WriteLine("To Login enter 1 to Register enter 2 :");
+ input = Console.ReadLine();
+ if(input.Equals("1") || input.Equals("2") ){
+ break;
+ }
+ else
+ {
+ Console.WriteLine("You Entered an invalid value " + input);
+ }
+
+ }
+
+ Bank user = null;
+ bool registered = false;
+
+ switch(input)
+ {
+ case "1":
+ user = LoginPresentation.PresentLogin(fileName);
+ break;
+ case "2":
+ registered = RegistrationPresentation.PresentRegister(fileName);
+ break;
+ default:
+ Console.WriteLine("Invalid");
+ break;
+ }
+
+ if(input == "1" && user != null)
+ {
+ AccountPresentation.PresentAccount(user, fileName);
+ Console.ReadKey();
+ }
+ else if(input == "2" && registered) { Present(fileName); }
+
+
+
+ }
+ }
+}
diff --git a/sav_bank/presentation/RegistrationPresentation.cs b/sav_bank/presentation/RegistrationPresentation.cs
new file mode 100644
index 0000000..2b79ad9
--- /dev/null
+++ b/sav_bank/presentation/RegistrationPresentation.cs
@@ -0,0 +1,70 @@
+using sav_bank.service;
+using sav_bank.utils;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace sav_bank.presentation
+{
+ public class RegistrationPresentation
+ {
+ public static bool PresentRegister(string fileName) {
+ Console.WriteLine("Fill in the following details to register");
+ Console.Write("First Name: ");
+ string firstName = Console.ReadLine();
+ VerifyInput.VerifyEmptyOrNull(firstName);
+ Console.Write("Last Name: ");
+ string lastName = Console.ReadLine();
+ VerifyInput.VerifyEmptyOrNull(lastName);
+ Console.Write("Username: ");
+ string userName = Console.ReadLine();
+ VerifyInput.VerifyEmptyOrNull(userName);
+ Console.Write("Email: ");
+ string email = Console.ReadLine();
+ VerifyInput.VerifyEmptyOrNull(email);
+ Console.Write("Phone Number: ");
+ string phoneNumber = Console.ReadLine();
+ VerifyInput.VerifyEmptyOrNull(phoneNumber);
+ Console.Write("Age: ");
+ string age = Console.ReadLine();
+ VerifyInput.VerifyEmptyOrNull(age);
+ Console.Write("Password: ");
+ string password = Console.ReadLine();
+ VerifyInput.VerifyEmptyOrNull(password);
+
+ var dto = new SignUpDtos()
+ {
+ FirstName = firstName,
+ LastName = lastName,
+ UserName = userName,
+ Email = email,
+ PhoneNumber = phoneNumber,
+ Age = age,
+ Password = password,
+
+ };
+
+ var signUp = RegisterService.RegisterUser(dto, fileName);
+ if (signUp.Code.Equals("00"))
+ {
+
+
+ SymbolWriter.WriteSymbol();
+ Console.WriteLine("Account created successfully Procceed to login");
+ SymbolWriter.WriteSymbol();
+
+ }
+ else
+ {
+
+ Console.WriteLine(signUp.Description);
+ Console.WriteLine("Try again")
+ ;
+ PresentRegister(fileName);
+ }
+ return signUp.Data;
+ }
+ }
+}
diff --git a/sav_bank/sav_bank.csproj b/sav_bank/sav_bank.csproj
new file mode 100644
index 0000000..d215711
--- /dev/null
+++ b/sav_bank/sav_bank.csproj
@@ -0,0 +1,151 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {04E34733-76C1-48C2-98B4-A267DB477078}
+ Exe
+ sav_bank
+ sav_bank
+ v4.7.2
+ 512
+ true
+ true
+
+
+ AnyCPU
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ AnyCPU
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+ packages\Microsoft.Bcl.AsyncInterfaces.7.0.0\lib\net462\Microsoft.Bcl.AsyncInterfaces.dll
+
+
+ packages\Microsoft.Extensions.Configuration.7.0.0\lib\net462\Microsoft.Extensions.Configuration.dll
+
+
+ packages\Microsoft.Extensions.Configuration.Abstractions.7.0.0\lib\net462\Microsoft.Extensions.Configuration.Abstractions.dll
+
+
+ packages\Microsoft.Extensions.Configuration.FileExtensions.7.0.0\lib\net462\Microsoft.Extensions.Configuration.FileExtensions.dll
+
+
+ packages\Microsoft.Extensions.Configuration.Json.7.0.0\lib\net462\Microsoft.Extensions.Configuration.Json.dll
+
+
+ packages\Microsoft.Extensions.DependencyInjection.Abstractions.7.0.0\lib\net462\Microsoft.Extensions.DependencyInjection.Abstractions.dll
+
+
+ packages\Microsoft.Extensions.FileProviders.Abstractions.7.0.0\lib\net462\Microsoft.Extensions.FileProviders.Abstractions.dll
+
+
+ packages\Microsoft.Extensions.FileProviders.Physical.7.0.0\lib\net462\Microsoft.Extensions.FileProviders.Physical.dll
+
+
+ packages\Microsoft.Extensions.FileSystemGlobbing.7.0.0\lib\net462\Microsoft.Extensions.FileSystemGlobbing.dll
+
+
+ packages\Microsoft.Extensions.Primitives.7.0.0\lib\net462\Microsoft.Extensions.Primitives.dll
+
+
+
+ packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll
+
+
+
+
+ packages\System.IO.4.3.0\lib\net462\System.IO.dll
+ True
+ True
+
+
+ packages\System.Memory.4.5.5\lib\net461\System.Memory.dll
+
+
+
+ packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll
+
+
+ packages\System.Runtime.4.3.0\lib\net462\System.Runtime.dll
+ True
+ True
+
+
+ packages\System.Runtime.CompilerServices.Unsafe.6.0.0\lib\net461\System.Runtime.CompilerServices.Unsafe.dll
+
+
+ packages\System.Security.Cryptography.Algorithms.4.3.1\lib\net463\System.Security.Cryptography.Algorithms.dll
+ True
+ True
+
+
+ packages\System.Security.Cryptography.Encoding.4.3.0\lib\net46\System.Security.Cryptography.Encoding.dll
+ True
+ True
+
+
+ packages\System.Security.Cryptography.Primitives.4.3.0\lib\net46\System.Security.Cryptography.Primitives.dll
+ True
+ True
+
+
+ packages\System.Text.Encodings.Web.7.0.0\lib\net462\System.Text.Encodings.Web.dll
+
+
+ packages\System.Text.Json.7.0.0\lib\net462\System.Text.Json.dll
+
+
+ packages\System.Threading.Tasks.Extensions.4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll
+
+
+ packages\System.ValueTuple.4.5.0\lib\net47\System.ValueTuple.dll
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/sav_bank/sav_bank.sln b/sav_bank/sav_bank.sln
new file mode 100644
index 0000000..4c737c9
--- /dev/null
+++ b/sav_bank/sav_bank.sln
@@ -0,0 +1,25 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.4.33205.214
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "sav_bank", "sav_bank.csproj", "{04E34733-76C1-48C2-98B4-A267DB477078}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {04E34733-76C1-48C2-98B4-A267DB477078}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {04E34733-76C1-48C2-98B4-A267DB477078}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {04E34733-76C1-48C2-98B4-A267DB477078}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {04E34733-76C1-48C2-98B4-A267DB477078}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {FD1A3EBF-FC05-427A-9CA9-D4C8F8DABA35}
+ EndGlobalSection
+EndGlobal
diff --git a/sav_bank/service/Account.cs b/sav_bank/service/Account.cs
new file mode 100644
index 0000000..12b3833
--- /dev/null
+++ b/sav_bank/service/Account.cs
@@ -0,0 +1,81 @@
+using sav_bank.data;
+using sav_bank.model;
+using sav_bank.utils;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace sav_bank.service
+{
+ public class AccountService
+ {
+
+ public static BankResponse GetAccountBalance(String userName, string fileName)
+ {
+ var user = DataBase.GetDataByUserId(userName, fileName);
+ if (user == null)
+ return new BankResponse() { Code = "25", Description = "User does not exist", Data = 0 };
+
+ Console.WriteLine(user.Balance);
+
+ return new BankResponse() { Code = "00", Description = "Success", Data = user.Balance };
+
+ }
+
+ public static BankResponse> GetAccountSummary(String userName, string fileName)
+ {
+ var user = DataBase.GetDataByUserId(userName, fileName);
+ if (user == null)
+ return new BankResponse> { Code = "25", Description = "User does not exist", Data = null };
+
+ if(user.AccountSummary == null || (user.AccountSummary != null && !user.AccountSummary.Any()))
+ return new BankResponse> { Code = "25", Description = "no records found", Data = null };
+
+ return new BankResponse> { Code = "00", Description = "Success", Data = user.AccountSummary };
+
+ }
+ public static BankResponse DepositAccount(String userName, string fileName)
+ {
+ Console.Write("Enter amount:");
+ string input = Console.ReadLine();
+
+ VerifyInput.VerifyEmptyOrNull(input);
+ int amount = int.Parse(input);
+ var user = DataBase.GetDataByUserId(userName, fileName);
+ if (user == null)
+ return new BankResponse() { Code = "25", Description = "User does not exist", Data = 0 };
+
+ var updated = user.AddAcountBalance(amount);
+ if (updated == -1)
+ return new BankResponse() { Code = "25", Description = "Invalid amount", Data = 0 };
+
+ DataBase.Update(user, fileName);
+ return new BankResponse() { Code = "00", Description = "Success", Data = user.Balance };
+
+ }
+ public static BankResponse Withdraw(String userName, string fileName)
+ {
+
+ Console.Write("Enter amount:");
+ string input = Console.ReadLine();
+
+ VerifyInput.VerifyEmptyOrNull(input);
+ int amount = int.Parse(input);
+
+ var user = DataBase.GetDataByUserId(userName, fileName);
+ if (user == null)
+ return new BankResponse() { Code = "25", Description = "User does not exist", Data = 0 };
+
+ var updated = user.Withdraw(amount);
+ if(updated == -1)
+ return new BankResponse() { Code = "25", Description = "Low balance", Data = 0 };
+
+
+ DataBase.Update(user, fileName);
+ return new BankResponse() { Code = "00", Description = "Success", Data = user.Balance };
+
+ }
+ }
+}
diff --git a/sav_bank/service/Login.cs b/sav_bank/service/Login.cs
new file mode 100644
index 0000000..87abe66
--- /dev/null
+++ b/sav_bank/service/Login.cs
@@ -0,0 +1,36 @@
+using sav_bank.data;
+using sav_bank.model;
+using sav_bank.utils;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Runtime.InteropServices;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace sav_bank.service
+{
+ public class LoginService
+ {
+
+
+ public static BankResponse UserLogin(string username, string password, string fileName)
+ {
+
+ if (string.IsNullOrEmpty(username) || string.IsNullOrEmpty(password))
+ return new BankResponse() { Code = "25", Description = "Null Fields", Data = null };
+
+
+ var user = DataBase.GetDataByUserId(username, fileName);
+ if (user == null)
+ return new BankResponse() { Code = "25", Description = "User does not exist", Data = null };
+
+ if (!PasswordHelper.VerifyPasswordHash(password, user.PasswordHash, user.PasswordSalt))
+ return new BankResponse() { Code = "25", Description = "Incorrect Username or Password", Data = null };
+
+
+ return new BankResponse() { Code = "00", Description = "Successfull", Data = user };
+
+ }
+ }
+}
diff --git a/sav_bank/service/Register.cs b/sav_bank/service/Register.cs
new file mode 100644
index 0000000..388ce59
--- /dev/null
+++ b/sav_bank/service/Register.cs
@@ -0,0 +1,34 @@
+using sav_bank.data;
+using sav_bank.model;
+using sav_bank.utils;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace sav_bank.service
+{
+ public class RegisterService
+ {
+ public static BankResponse RegisterUser(SignUpDtos dto, string fileName) {
+
+ var user = DataBase.GetDataByUserId(dto.UserName, fileName);
+ if (user != null)
+ return new BankResponse() { Code = "25", Description = "Username exist Already", Data = false };
+
+ PasswordHelper.CreatePasswordHash(dto.Password, out byte[] passwordHash, out byte[] passwordSalt);
+ var bankModel = new Bank(userName: dto.UserName, phoneNumber: dto.PhoneNumber,firstName: dto.FirstName, lastName: dto.LastName, email: dto.Email, age: dto.Age, passwordSalt :passwordSalt, passwordHash: passwordHash) {};
+
+ var added = DataBase.AddData(bankModel, fileName);
+ if(!added)
+ return new BankResponse() { Code = "25", Description = "Error creating account please try again", Data = false };
+
+
+ return new BankResponse() { Code = "00", Description = "Success", Data = true };
+
+
+
+ }
+ }
+}
diff --git a/sav_bank/utils/PasswordHelper.cs b/sav_bank/utils/PasswordHelper.cs
new file mode 100644
index 0000000..b6085f7
--- /dev/null
+++ b/sav_bank/utils/PasswordHelper.cs
@@ -0,0 +1,61 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace sav_bank.utils
+{
+ internal class PasswordHelper
+ {
+ public static void CreatePasswordHash(string password, out byte[] passwordHash, out byte[] passwordSalt)
+ {
+ if (password == null) throw new ArgumentNullException("password");
+ if (string.IsNullOrWhiteSpace(password)) throw new ArgumentException("Value cannot be empty or whitespace only string.", "password");
+
+ var hmac = new System.Security.Cryptography.HMACSHA512();
+ passwordSalt = hmac.Key;
+ passwordHash = hmac.ComputeHash(System.Text.Encoding.UTF8.GetBytes(password));
+ }
+
+ public static bool VerifyPasswordHash(string password, byte[] storedHash, byte[] storedSalt)
+ {
+ if (password == null) throw new ArgumentNullException("password");
+ if (string.IsNullOrWhiteSpace(password)) throw new ArgumentException("Value cannot be empty or whitespace only string.", "password");
+ if (storedHash.Length != 64) throw new ArgumentException("Invalid length of password hash (64 bytes expected).", "passwordHash");
+ if (storedSalt.Length != 128) throw new ArgumentException("Invalid length of password salt (128 bytes expected).", "passwordHash");
+
+ using (var hmac = new System.Security.Cryptography.HMACSHA512(storedSalt))
+ {
+ var computedHash = hmac.ComputeHash(System.Text.Encoding.UTF8.GetBytes(password));
+ for (int i = 0; i < computedHash.Length; i++)
+ {
+ if (computedHash[i] != storedHash[i]) return false;
+ }
+ }
+
+ return true;
+ }
+ public static string GenerateAccountNumber()
+ {
+ Random generator = new Random();
+ string r = generator.Next(0, 1000000).ToString("D11");
+ if (r.Distinct().Count() == 1)
+ {
+ r = GenerateAccountNumber();
+ }
+ return r;
+ }
+
+ public static string GenerateUserId()
+ {
+ Random generator = new Random();
+ string r = generator.Next(0, 1000000).ToString("D5");
+ if (r.Distinct().Count() == 1)
+ {
+ r = GenerateUserId();
+ }
+ return r;
+ }
+ }
+}
diff --git a/sav_bank/utils/SymbolWriter.cs b/sav_bank/utils/SymbolWriter.cs
new file mode 100644
index 0000000..5575c75
--- /dev/null
+++ b/sav_bank/utils/SymbolWriter.cs
@@ -0,0 +1,18 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace sav_bank.utils
+{
+ public class SymbolWriter
+ {
+ public static void WriteSymbol(int length = 50, string symbol = "=")
+ {
+ for (var i = 0; i < length; i++)
+ Console.Write(symbol);
+ Console.WriteLine("");
+ }
+ }
+}
diff --git a/sav_bank/utils/VerifyInput.cs b/sav_bank/utils/VerifyInput.cs
new file mode 100644
index 0000000..45a4a99
--- /dev/null
+++ b/sav_bank/utils/VerifyInput.cs
@@ -0,0 +1,27 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace sav_bank.utils
+{
+ public class VerifyInput
+ {
+ public static string VerifyEmptyOrNull(string input)
+ {
+ while (
+ string.IsNullOrEmpty(input)
+
+ )
+ {
+ Console.WriteLine("Input must not be empty");
+ Console.Write("Please input new value: ");
+ input = Console.ReadLine();
+ }
+
+
+ return input;
+ }
+ }
+}