Files
ophelias-oasis/OpheliasOasis/Program.cs
雲華 34bebca414 Finishes the guest part of the models and UI integration
This commit branch has been muddled with changes that are out of scope
and cover more than just the models. Specifically it includes
completion of basic guest related models, database access, command line interface
integration and preventing SQL injection.

Total summary of changes:

**IMPORTANT CHANGE: All queries are now parameterized to prevent SQL
injections. Prior versions are subject to it since the strings were
built.

- HotelManager
This class is used to provide database operations that are outside of
scope from a given model. Furthermore if there is no model to work off
of, such as creating a new model based off an existing entry, these
functions live outside of the model since it makes no sense for models
to contain functions where it would retrieve itself with no context.
Realistically this could be placed in an empty constructor and address
itself, however, for now this functionality has been moved off the model
since it is a one use and is not guaranteed to generate a guest. Some
functionality for the coming employee management functions are already
in there since they share overlap with the guest module. Specifically
GetBaseRate for checking and getting the base rate.

- DatabaseManager
This class has mostly migrated functionality out or switch to
parameterized query generation to prevent SQL injections.

- Guest, Reservation, and Transaction Classes
Migrated functionality to create the database entry and a new entry of
guest upon creation as well as update them.

- Program (Terminal app)
Fully integrated the guest module. Has not undergone extensive testing
but does work as of this commit.
2022-04-15 02:29:55 -04:00

534 lines
22 KiB
C#

using Ophelias.Models;
using Ophelias.Managers;
using Ophelias.Expressions;
using System.Data.SQLite;
class Program
{
private static void GuestMode()
{
Reservation? activeReservation = null;
Guest? activeGuest = null;
void help()
{
Console.WriteLine(
"Reservation Commands:\n" +
"\treservation create - Create a new reservation.\n" +
"\treservation update - Update your active reservation.\n" +
"\treservation cancel - Cancel a reservation.\n" +
"Account Commands:\n" +
"\taccount create - Create a new guest account.\n" +
"\taccount update - Update your account information.\n" +
"\taccount login - Log into your guest account." +
"Enter Q to quit.\n"
);
return;
}
(string?, string?, string?) GetCreditCardInformation()
{
Console.Write("What is your credit card number: ");
string CreditCard = "";
while (!Validation.ValidateCreditCard(CreditCard))
{
CreditCard = Console.ReadLine().Trim().Replace("\t", "");
if (CreditCard == "q" || CreditCard == "Q")
return (null, null, null);
if (!Validation.ValidateCreditCard(CreditCard))
Console.Write("Please enter a valid credit card. If your card is expired, enter Q to cancel: ");
}
Console.Write("What is your credit card expiration date (MM/yy): ");
string CardExpiration = "";
while (!Validation.ValidateExpirationDate(CardExpiration))
{
CardExpiration = Console.ReadLine().Trim().Replace("\t", "");
if (CardExpiration == "q" || CardExpiration == "Q")
return (null, null, null);
if (!Validation.ValidateExpirationDate(CardExpiration))
Console.Write("Please enter a valid expiration date. If your card is expired, enter Q to cancel: ");
}
Console.Write("What is your credit card CCV: ");
string CCV = "";
while (!Validation.ValidateCCV(CCV))
{
CCV = Console.ReadLine().Trim().Replace("\t", "");
if (CCV == "q" || CCV == "Q")
return (null, null, null);
if (!Validation.ValidateCCV(CCV))
Console.Write("Please enter a valid credit card CCV. If your card is expired, enter Q to cancel: ");
}
return (CreditCard, CardExpiration, CCV);
}
(string, string) GetGuestName() {
Console.Write("What is your first name: ");
string FirstName = "";
while (FirstName.Length == 0)
{
FirstName = Console.ReadLine();
if (FirstName == "")
Console.Write("What is your first name: ");
}
Console.Write("What is your last name: ");
string LastName = "";
while (LastName.Length == 0)
{
LastName = Console.ReadLine();
if (LastName == "")
Console.Write("What is your last name: ");
}
return (FirstName, LastName);
}
string GetGuestEmail()
{
Console.Write("What is your email: ");
string Email = "";
while (!Validation.ValidateEmail(Email))
{
Email = Console.ReadLine();
if (!Validation.ValidateEmail(Email))
Console.Write("Please enter a valid email: ");
}
return Email;
}
void GuestLogin()
{
Console.Write("\nEnter your email address: ");
string email = "";
while (!Validation.ValidateEmail(email))
{
email = Console.ReadLine();
if (!Validation.ValidateEmail(email))
Console.Write("Please enter a valid email: ");
}
activeGuest = HotelManager.GetGuestByEmail(email);
if (activeGuest == null)
{
Console.WriteLine($"\nNo account was found with the email {email}.");
return;
}
Console.WriteLine($"\nYou have logged into {activeGuest.FirstName} {activeGuest.LastName} ({email}).");
activeReservation = HotelManager.GetResByGuestAndDate(activeGuest);
}
void CreateNewGuestPrompt()
{
(string FirstName, string LastName) = GetGuestName();
string Email = GetGuestEmail();
Console.Write("Would you like to enter your credit card details? (Y/n): ");
string? CreditCard = null;
string? CardExpiration = null;
string? CCV = null;
if (Console.ReadLine().Equals("y") || Console.ReadLine().Equals("Y"))
(CreditCard, CardExpiration, CCV) = GetCreditCardInformation();
activeGuest = new Guest(FirstName, LastName, Email, CreditCard: CreditCard, Expiration: CardExpiration, CCV: CCV);
Console.Write($"You are now logged in as {FirstName} {LastName} ({Email})");
}
void UpdateGuestInformation()
{
if (activeGuest == null)
{
Console.WriteLine("No guest is currently logged in, please login.");
return;
}
string? NewFname = null, NewLname = null, NewEmail = null, NewCard = null, NewExpiry = null, NewCCV = null;
void SavePrompt()
{
if (NewFname == null && NewLname == null && NewEmail == null && NewCard == null && NewExpiry == null && NewCCV == null)
{
Console.WriteLine("No changes have been made.");
return;
}
string changes = "";
List<string> NewDetails = new List<string>();
if (!string.IsNullOrEmpty(NewFname))
{
NewDetails.Add($"\tFirst Name: {activeGuest.FirstName} -> {NewFname}");
activeGuest.FirstName = NewFname;
}
if (!string.IsNullOrEmpty(NewLname))
{
NewDetails.Add($"\tLast Name: {activeGuest.LastName} -> {NewLname}");
activeGuest.LastName = NewLname;
}
if (!string.IsNullOrEmpty(NewEmail))
{
NewDetails.Add($"\tEmail: {activeGuest.Email} -> {NewEmail}");
activeGuest.Email = NewEmail;
}
if (!string.IsNullOrEmpty(NewCard))
{
NewDetails.Add($"\tCredit Card: {activeGuest.CreditCard} -> {NewCard}");
activeGuest.CreditCard = NewCard;
}
if (!string.IsNullOrEmpty(NewExpiry))
{
NewDetails.Add($"\tCard Expiration Date: {activeGuest.Expiration} -> {NewExpiry}");
activeGuest.Expiration = NewExpiry;
}
if (!string.IsNullOrEmpty(NewCCV))
{
NewDetails.Add($"\tCard CCV: {activeGuest.CCV} -> {NewCCV}");
activeGuest.CCV = NewCCV;
}
if (NewDetails.Count > 0)
changes += string.Join("\n", NewDetails);
Console.WriteLine($"The following changes have been made:\n {changes}");
activeGuest.UpdateGuest(activeGuest.Id, NewFname, NewLname, NewEmail, NewCard, NewExpiry, NewCCV);
return;
}
Console.WriteLine($"You are currently logged in as {activeGuest.FirstName} {activeGuest.LastName} ({activeGuest.Email}).\n" +
$"If this is not your account, please (Q)uit and log into your account. Changes will be recorded, but not saved\n" +
$"until you enter S.\n");
do
{
Console.Write("Please select the option you would like to change or enter S to save:\n" +
"1. First Name and Last Name\n" +
"2. Email Address\n" +
"3. Credit Card Information\n");
switch (Console.ReadLine())
{
case "Q": return;
case "1": (NewFname, NewLname) = GetGuestName(); break;
case "2": NewEmail = GetGuestEmail(); break;
case "3": (NewCard, NewExpiry, NewCCV) = GetCreditCardInformation(); break;
case "S": SavePrompt(); return;
default: break;
}
} while (true);
}
ReservationType SelectReservation()
{
string input = "";
Console.Write("What kind of reservation would you like to make?\n" +
"1. Conventional\n" +
"2. Prepaid\n" +
"3. 60 Day Advance\n" +
"4. Incentive\n" +
"Input a number: ");
while (true)
{
input = Console.ReadLine();
if (input == "1" || input == "2" || input == "3" || input == "4")
break;
Console.Write("Please enter either 1, 2, 3, or 4: ");
}
return (ReservationType)Convert.ToInt32(input);
}
(DateTime, DateTime) SelectDate()
{
string input = "";
DateTime _StartDate;
DateTime _EndDate;
Console.Write("When would you like to begin your stay.\n" +
"Your date input should be in in the following format - yyyy-MM-dd. Example: (2021-12-31)?\n" +
"Input a date (2021-12-31): ");
while (true)
{
input = Console.ReadLine();
if (DateTime.TryParse(input, out _StartDate))
break;
Console.Write("Please enter a valid date (2021-12-31): ");
}
Console.Write("When would you like to end your stay.\n" +
"Your date input should be in in the following format - yyyy-MM-dd. Example: (2021-12-31)?\n" +
"Input a date (2021-12-31): ");
while (true)
{
input = Console.ReadLine();
if (DateTime.TryParse(input, out _EndDate) && _EndDate > _StartDate)
break;
if (_EndDate < _StartDate)
Console.Write("End date cannot be before start date. Please enter a valid date (2021-12-31): ");
else
Console.Write("Please enter a valid date (2021-12-31): ");
}
return (_StartDate.Date, _EndDate.Date);
}
void EditReservationPrompt()
{
string input;
DateTime NewStartDate = activeReservation.StartDate, NewEndDate = activeReservation.EndDate;
ReservationType NewType = activeReservation.Type;
bool completed = false;
do
{
Console.Write("What information would you like to edit?\n" +
"If not and you wish to cancel, enter Q to exit. If you want to save and complete your changes, enter S.\n" +
"1. Reservation type\n" +
"2. Reservation dates\n" +
"Enter 1 or 2: ");
input = Console.ReadLine();
switch (input)
{
case "Q": Console.WriteLine("Changes have has been deleted."); return;
case "1": NewType = SelectReservation(); break;
case "2": (NewStartDate, NewEndDate) = SelectDate(); break;
case "S":
completed = true;
(activeReservation.Type, activeReservation.StartDate, activeReservation.EndDate) = (NewType, NewStartDate, NewEndDate);
break;
default: break;
}
} while (!completed);
}
void CreateNewReservation()
{
if (activeGuest == null)
{
Console.WriteLine("No guest is currently logged in, please login.");
return;
}
if (activeReservation != null)
{
Console.WriteLine("You currently have an active registration.");
return;
}
if (HotelManager.GetBaseRate() == null)
{
Console.WriteLine("Unable to proceed with reservation due to no base rate being set. Please inform an employee.");
return;
}
string input;
ReservationType Type;
DateTime StartDate;
DateTime EndDate;
Type = SelectReservation();
(StartDate, EndDate) = SelectDate();
while((Type != ReservationType.SixtyDayAdvance &&
(activeGuest.CreditCard == null || activeGuest.Expiration == null || activeGuest.CCV == null))) {
Console.Write("The reservation type you chose requires you to specify your credit card.\n" +
"If you are unable to provide one, enter Q to quit or hit enter to continue.\n" +
": ");
input = Console.ReadLine();
if (input == "Q")
return;
GetCreditCardInformation();
}
Console.Write($"Thank you for filling out your reservation details. Currently you have made a {Type} " +
$"reservation and are scheduled to stay from {StartDate.ToString("yyyy-MM-dd")} to {EndDate.ToString("yyyy-MM-dd")}." +
$"If these details are correct, enter YES to complete. To cancel your reservation enter Q. Enter NO to edit your reservation.\n" +
$": ");
input = Console.ReadLine();
while(input != "YES")
{
if (input == "NO")
{
EditReservationPrompt();
Console.Write("You're changes have been saved. Are you done with your changes?\n" +
"Enter YES to finish, NO to continue editing, or Q to discard your reservation.\n" +
": ");
input = Console.ReadLine();
}
else if (input == "Q")
{
Console.WriteLine("Reservation has been deleted.");
return;
} else
{
Console.WriteLine("Input must be YES, NO, or Q.\n: ");
input = Console.ReadLine();
}
}
activeReservation = new Reservation(activeGuest, Type, DateTime.Now.Date, StartDate, EndDate);
Console.WriteLine("Your reservation has been made.");
}
void UpdateReservation()
{
string input = "NO";
if (activeGuest == null)
{
Console.WriteLine("No guest is currently logged in, please login.");
return;
}
if (activeReservation == null)
{
Console.WriteLine("You currently do not have an active registration.");
return;
}
Console.Write("Your current reservation details are:\n" +
$"\tStarts on: {activeReservation.StartDate.ToString("yyyy-MM-dd")}\n" +
$"\tEnds on: {activeReservation.EndDate.ToString("yyyy-MM-dd")}\n");
DateTime? _StartDate = null, _EndDate = null;
do
{
if (input == "NO")
{
(_StartDate, _EndDate) = SelectDate();
if (_StartDate.HasValue && _EndDate.HasValue)
Console.Write("Your new reservation details are:\n" +
$"\tStarts on: {activeReservation.StartDate.ToString("yyyy-MM-dd")} -> {_StartDate.Value.ToString("yyyy-MM-dd")}\n" +
$"\tEnds on: {activeReservation.EndDate.ToString("yyyy-MM-dd")} -> {_EndDate.Value.ToString("yyyy-MM-dd")}\n");
Console.Write("Are you done with your changes?\n" +
"Enter YES to finish and save, NO to continue editing.\n" +
": ");
} else if (input == "Q")
{
Console.WriteLine("Your changes have been discarded.");
return;
}
else
{
Console.WriteLine("Input must be YES, NO, or Q.");
Console.Write(": ");
}
input = Console.ReadLine();
} while (input != "YES");
if (_StartDate != null && _EndDate != null)
{
activeReservation.ChangeReservationDates((DateTime)_StartDate, (DateTime)_EndDate);
Console.WriteLine("Your changes have been saved.");
}
return;
}
void CancelReservation()
{
if (activeGuest == null)
{
Console.WriteLine("No guest is currently logged in, please login.");
return;
}
if (activeReservation == null)
{
Console.WriteLine("You currently do not have an active registration.");
return;
}
string input;
Console.Write("Would you like to cancel your reservation?\n" +
"You may be charged depending on your reservation.\n" +
"Enter YES to confirm or NO to exit: ");
input = Console.ReadLine();
while(input != "YES")
{
if (input == "NO")
{
Console.Write("Reservation has not been cancelled.");
return;
} else
{
Console.Write("Your input must be YES or NO: ");
Console.ReadLine();
}
}
activeReservation.CancelReservation();
activeReservation = null;
Console.Write("Reservation has been cancelled, you may be charged based on your reservation.");
}
Console.Write(
"\nWelcome to the Ophelias Oasis Hotel Registration System!\n" +
"Type help to get a full list of commands or enter a command.\n" +
"Command: "
);
while (true)
{
string? input = Console.ReadLine();
switch(input)
{
case "help": help(); break;
case "reservation create": CreateNewReservation(); break;
case "reservation update": UpdateReservation(); break;
case "reservation cancel": CancelReservation(); break;
case "account create": CreateNewGuestPrompt(); break;
case "account update": UpdateGuestInformation(); break;
case "account login": GuestLogin(); break;
case "q": return;
default: Console.WriteLine("Unknown command, enter help for more inforamtion."); break;
}
Console.Write("\nCommand: ");
}
}
private void AdminMode()
{
void help()
{
Console.WriteLine(
"Report Commands:\n" +
"\tgenerate daily report - Generates a daily report on expected occupancy, room income, and incentive losses.\n" +
"\tgenerate operational report - Generates a report of daily arrivals and occupancy.\n" +
"\tgenerate accomodation bills - Generates an accomodation bill that will be handed to guests upon checkout.\n" +
"\treservation cancel\n" +
"Management Commands:" +
"\tcheckin guest - Checks in a guest and assigns them a room.\n" +
"\tcheckout guest - Checks out a guest and removes their room assignment.\n" +
"\tbaserate set - Sets a new base rate to begin after a specified date.\n" +
"Enter Q to quit.\n"
);
return;
}
void SetFutureBaseRate()
{
if (HotelManager.GetBaseRate() == null)
{
Console.Write("No base rate has been configured. " +
"You must set one for the current date.\n" +
"Enter new rate: ");
Console.ReadLine();
}
}
while (true)
{
string? input = Console.ReadLine();
switch (input)
{
case "help": help(); break;
case "generate daily report": break;
case "generate operational report": break;
case "generate accomodation bills": break;
case "reservation cancel": break;
case "checkin guest": break;
case "checkout guest": break;
case "baserate set": break;
case "Q": return;
default: Console.WriteLine("Unknown command, enter help for more inforamtion."); break;
}
Console.Write("\nCommand: ");
}
}
static void Main()
{
if (!File.Exists("database.sqlite3") || new FileInfo("database.sqlite3").Length == 0)
{
SQLiteConnection.CreateFile("database.sqlite3");
using (DatabaseManager Manager = new DatabaseManager())
{
Manager.InitializeTables();
Manager.InitializeRoomsTable();
}
}
bool run = true;
while (run)
{
Console.Write(
"Are you an employee or customer?\n" +
"1. Employee\n" +
"2. Customer/ Guest\n" +
": "
);
switch(Console.ReadLine().ToUpper())
{
case "1": break;
case "2": GuestMode(); break;
case "Q": run = false; break;
default: Console.WriteLine("You must either specify 1 for Employee, 2 for Customer/ Guest, or Q to quit.\n\n"); break;
}
}
}
}