This commit adds another piece of functinality allowing the staff to issue penalties. This currently just charges users for their owed amount and there are no actual penalty fees. The design document did not call for that. There is also some documentation that was written. The next several set of commits are likely to be documentation.
1075 lines
45 KiB
C#
1075 lines
45 KiB
C#
using Ophelias.Expressions;
|
|
using Ophelias.Managers;
|
|
using Ophelias.Models;
|
|
using Ophelias.Reporting;
|
|
using System.Data.SQLite;
|
|
|
|
internal class Program
|
|
{
|
|
private static string GetGuestEmail()
|
|
{
|
|
Console.Write("Specify email: ");
|
|
string Email = "";
|
|
while (!Validation.ValidateEmail(Email))
|
|
{
|
|
Email = Console.ReadLine();
|
|
if (!Validation.ValidateEmail(Email))
|
|
{
|
|
Console.Write("Please enter a valid email: ");
|
|
}
|
|
}
|
|
return Email;
|
|
}
|
|
|
|
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" +
|
|
"\treservation pay - Pays in full for an active 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 or 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);
|
|
}
|
|
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 = Hotel.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 = Hotel.GetResByGuest(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;
|
|
while (true)
|
|
{
|
|
string input = Console.ReadLine();
|
|
if (input.Equals("y") || input.Equals("Y"))
|
|
{
|
|
(CreditCard, CardExpiration, CCV) = GetCreditCardInformation();
|
|
break;
|
|
}
|
|
else if (input.Equals("n") || input.Equals("N"))
|
|
{
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
Console.Write("Input must be Y, y or N, n: ");
|
|
}
|
|
}
|
|
|
|
activeGuest = new(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();
|
|
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);
|
|
activeReservation.Guest = activeGuest;
|
|
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) - 1);
|
|
}
|
|
bool CheckReservationRestrictions(DateTime Date, ReservationType Type)
|
|
{
|
|
if (Type == ReservationType.Prepaid)
|
|
{
|
|
if ((int)(Date - DateTime.Now).TotalDays < 90)
|
|
{
|
|
Console.WriteLine("Prepaid reservations must be made 90 days in advance.");
|
|
}
|
|
else
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
else if (Type == ReservationType.SixtyDayAdvance)
|
|
{
|
|
if ((int)(Date - DateTime.Now).TotalDays < 60)
|
|
{
|
|
Console.WriteLine("Sixty-days-in-advance reservations must be made 60 days in advance.");
|
|
}
|
|
else
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
(DateTime?, DateTime?) SelectDate(ReservationType Type)
|
|
{
|
|
|
|
(DateTime, DateTime) Dates()
|
|
{
|
|
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) && _StartDate >= DateTime.Now)
|
|
{
|
|
break;
|
|
}
|
|
|
|
if (_StartDate <= DateTime.Now)
|
|
{
|
|
Console.Write("Start date cannot be before current date. Please enter a valid date (2021-12-31): ");
|
|
}
|
|
else
|
|
{
|
|
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 must be after 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);
|
|
}
|
|
|
|
DateTime StartDate;
|
|
DateTime EndDate;
|
|
string input;
|
|
|
|
while (true)
|
|
{
|
|
bool maxCapacity = false;
|
|
(StartDate, EndDate) = Dates();
|
|
if (StartDate == null || EndDate == null)
|
|
{
|
|
(_, maxCapacity) = Hotel.AvgOccupancySpan(StartDate, EndDate);
|
|
}
|
|
|
|
if (!maxCapacity)
|
|
{
|
|
if (!CheckReservationRestrictions(StartDate, Type))
|
|
{
|
|
Console.Write("Do you want to quit? Type YES to quit and discard, enter anything or nothing to select another date range.\n" +
|
|
": ");
|
|
input = Console.ReadLine();
|
|
if (input == "YES")
|
|
{
|
|
Console.WriteLine("Aborting reservation changes.");
|
|
return (null, null);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Console.WriteLine("Your reservation covers a range where we are already at max capacity, please change your reservation dates.");
|
|
}
|
|
|
|
}
|
|
return (StartDate, EndDate);
|
|
|
|
}
|
|
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(NewType); break;
|
|
case "S":
|
|
if (NewStartDate == null || NewEndDate == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
while (CheckReservationRestrictions((DateTime)NewStartDate, NewType))
|
|
{
|
|
(NewStartDate, NewEndDate) = SelectDate(NewType);
|
|
if (NewStartDate == null || NewEndDate == null)
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
completed = true;
|
|
(activeReservation.Type, activeReservation.StartDate, activeReservation.EndDate) = (NewType, (DateTime)NewStartDate, (DateTime)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 (Hotel.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(Type);
|
|
if (StartDate == null || EndDate == null)
|
|
{
|
|
Console.WriteLine("Aborting reservation creation.");
|
|
return;
|
|
}
|
|
|
|
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.Value.ToString("yyyy-MM-dd")} to {EndDate.Value.ToString("yyyy-MM-dd")}." +
|
|
$"If these details are correct, enter YES to complete. To cancel your reservation enter Q.\n" +
|
|
$": ");
|
|
input = Console.ReadLine();
|
|
while (input != "YES")
|
|
{
|
|
if (input == "Q")
|
|
{
|
|
Console.WriteLine("Reservation has been deleted.");
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
Console.Write("Input must be YES or Q.\n: ");
|
|
input = Console.ReadLine();
|
|
}
|
|
}
|
|
if (Type == ReservationType.Prepaid)
|
|
{
|
|
activeReservation = new(activeGuest, Type, DateTime.Now.Date, StartDate.Value, EndDate.Value);
|
|
activeReservation.Transaction.Pay(activeReservation.Transaction.Owed, activeGuest.CreditCard);
|
|
}
|
|
else
|
|
{
|
|
activeReservation = new(activeGuest, Type, DateTime.Now.Date, StartDate.Value, EndDate.Value);
|
|
}
|
|
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(activeReservation.Type);
|
|
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.");
|
|
}
|
|
void PayForReservation()
|
|
{
|
|
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;
|
|
}
|
|
|
|
if (ReservationType.Incentive == activeReservation.Type)
|
|
{
|
|
Console.WriteLine("Incentive reservations are paid for when you check-out.");
|
|
return;
|
|
}
|
|
else if (ReservationType.Conventional == activeReservation.Type)
|
|
{
|
|
Console.WriteLine("Conventional reservations are paid for when you check-out.");
|
|
return;
|
|
}
|
|
else if (ReservationType.Prepaid == activeReservation.Type)
|
|
{
|
|
Console.WriteLine("Prepaid reservations are paid for when you create them.");
|
|
return;
|
|
} else if (ReservationType.SixtyDayAdvance == activeReservation.Type)
|
|
{
|
|
if(activeReservation.StartDate.AddDays(-30).Date < DateTime.Now.Date)
|
|
{
|
|
if (activeReservation.Transaction.Owed <= activeReservation.Transaction.AmountPaid)
|
|
{
|
|
Console.WriteLine("Your reservation has already been paid for.");
|
|
return;
|
|
}
|
|
activeReservation.CancelReservation();
|
|
Console.WriteLine("Your reservation has been cancelled because you failed to pay within the payment period.");
|
|
return;
|
|
}
|
|
}
|
|
|
|
string? cc, exp, ccv;
|
|
cc = activeGuest.CreditCard;
|
|
exp = activeGuest.Expiration;
|
|
ccv = activeGuest.CCV;
|
|
while (true)
|
|
{
|
|
if (cc == null || exp == null || ccv == null)
|
|
(cc, exp, ccv) = GetCreditCardInformation();
|
|
|
|
if (cc == null || exp == null || ccv == null)
|
|
{
|
|
Console.Write("Would you like to try again and enter your payment information? (Your reservation will not be canceled)\n" +
|
|
"YES or NO: ");
|
|
while (true)
|
|
{
|
|
string input = Console.ReadLine();
|
|
if (input == "YES")
|
|
{
|
|
break;
|
|
} else if (input == "NO")
|
|
{
|
|
Console.WriteLine("Payment has been aborted.");
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
Console.WriteLine("Input must be YES or NO.");
|
|
}
|
|
}
|
|
} else if (cc != null && exp != null && ccv != null)
|
|
{
|
|
if (ReservationType.SixtyDayAdvance == activeReservation.Type && ((DateTime.Parse(exp).Date < activeReservation.StartDate.AddDays(-30).Date) && (DateTime.Parse(exp).Date < activeReservation.StartDate.AddDays(-45).Date)))
|
|
{
|
|
Console.WriteLine("Your card expires too soon. Please enter the correct expiration date if incorrect or a new card.");
|
|
cc = null;
|
|
exp = null;
|
|
ccv = null;
|
|
}
|
|
else if (ReservationType.SixtyDayAdvance == activeReservation.Type && ((DateTime.Parse(exp).Date > activeReservation.StartDate.AddDays(-30).Date) && (DateTime.Parse(exp).Date > activeReservation.StartDate.AddDays(-45).Date)))
|
|
{
|
|
if (cc != activeGuest.CreditCard && exp != activeGuest.Expiration && ccv != activeGuest.CCV)
|
|
{
|
|
activeGuest.UpdateGuest(activeGuest.Id, CreditCard: cc, Expiration: exp, CCV: ccv);
|
|
activeReservation.Guest = activeGuest;
|
|
}
|
|
PaymentStatus ps = activeReservation.Transaction.Pay(activeReservation.Transaction.Owed, activeGuest.CreditCard);
|
|
if (ps == PaymentStatus.SuccessfulPayment)
|
|
{
|
|
Console.WriteLine("Your reservation has been paid for.");
|
|
return;
|
|
} else if (ps == PaymentStatus.FailedPayment)
|
|
{
|
|
Console.WriteLine("There was an error paying for your resevation. Try again later or contact the Ophelias Oasis team.");
|
|
return;
|
|
} else if (ps == PaymentStatus.AmountCannotZero)
|
|
{
|
|
Console.WriteLine("You cannot pay $0 or less than $0.");
|
|
return;
|
|
} else if (ps == PaymentStatus.MissingCreditCard)
|
|
{
|
|
Console.WriteLine("Credit Card information is missing. Payment could not be made.");
|
|
} else if (ps == PaymentStatus.AlreadyPaid)
|
|
{
|
|
Console.WriteLine("Your reservation has already been paid for.");
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
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 "reservation pay": PayForReservation(); break;
|
|
case "account create": CreateNewGuestPrompt(); break;
|
|
case "account update": UpdateGuestInformation(); break;
|
|
case "account login": GuestLogin(); break;
|
|
case "q": return;
|
|
case "Q": return;
|
|
default: Console.WriteLine("Unknown command, enter help for more inforamtion."); break;
|
|
}
|
|
Console.Write("\nCommand: ");
|
|
}
|
|
}
|
|
private static void AdminMode()
|
|
{
|
|
void help()
|
|
{
|
|
Console.WriteLine(
|
|
"Report Commands:\n" +
|
|
"\tgenerate management report - Generates a daily management report on expected occupancy, room income, and incentive losses.\n" +
|
|
"\tgenerate operational report - Generates a report of daily arrivals and occupancy.\n" +
|
|
"\tgenerate accommodation bills - Generates an accommodation bill that will be handed to guests upon checkout.\n" +
|
|
"\treservation cancel\n" +
|
|
"Management Commands:" +
|
|
"\nnotify pending payments - Generates and emails 60 day advance reservations that they must pay for their reservation or it will be cancelled." +
|
|
"\nissue penalties - Issues penalties for guests that are no shows." +
|
|
"\tcheckin guest - Checks in a guest and assigns them a room.\n" +
|
|
"\tcheckout guest - Checks out a guest and removes their room assignment.\n" +
|
|
"\tset rate - Sets a new base rate to begin after a specified date.\n" +
|
|
"Enter Q or q to quit.\n"
|
|
);
|
|
return;
|
|
}
|
|
|
|
void SetFutureBaseRate()
|
|
{
|
|
bool SetRatePrompt(DateTime? FixedDate = null)
|
|
{
|
|
string input;
|
|
string amount;
|
|
amount = Console.ReadLine();
|
|
if (Validation.ValidateMoney(amount))
|
|
{
|
|
Console.Write($"Is this the correct base rate {amount}?\n" +
|
|
$"Enter YES or NO: ");
|
|
input = Console.ReadLine();
|
|
while (input != "YES")
|
|
{
|
|
if (input == "NO")
|
|
{
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
Console.Write("Input must be YES or NO: ");
|
|
}
|
|
input = Console.ReadLine();
|
|
}
|
|
if (input == "YES")
|
|
{
|
|
if (FixedDate != null)
|
|
{
|
|
if (Hotel.GetBaseRateByDate((DateTime)FixedDate))
|
|
{
|
|
Console.Write("There is already a base rate configured for this date.\n" +
|
|
"If you are entering a new rate because one was not configured and got this error, type YES.\n" +
|
|
"Would you like to overwrite it (YES)? If not enter anything to continue.\n" +
|
|
": ");
|
|
if (Console.ReadLine() == "YES")
|
|
{
|
|
Hotel.UpdateBaseRate(Convert.ToDouble(amount), FixedDate.Value.Date, DefaultRate: true);
|
|
return true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Hotel.SetBaseRate(Convert.ToDouble(amount), (DateTime)FixedDate, true);
|
|
}
|
|
|
|
Console.WriteLine($"A base rate of {amount} has been set and will take effect immediately.");
|
|
}
|
|
else
|
|
{
|
|
DateTime StartDate;
|
|
Console.Write("When would you like the new rate to take effect.\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))
|
|
{
|
|
if (StartDate.Date <= DateTime.Now.Date)
|
|
{
|
|
Console.WriteLine("Base rate must be configured for a future night. Not the same day or past.");
|
|
}
|
|
else if (Hotel.GetBaseRateByDate(StartDate))
|
|
{
|
|
Console.Write("There is already a base rate configured for this date.\n" +
|
|
"Would you like to overwrite it (YES)? If not enter anything to continue." +
|
|
": ");
|
|
if (Console.ReadLine() == "YES")
|
|
{
|
|
Hotel.UpdateBaseRate(Convert.ToDouble(amount), StartDate.Date);
|
|
return true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
Console.Write("Please enter a valid date (2021-12-31): ");
|
|
}
|
|
Hotel.SetBaseRate(Convert.ToDouble(amount), StartDate);
|
|
Console.WriteLine($"A base rate of {amount} has been set and will take effect on {DateTime.Now.Date.ToString("yyyy-MM-dd")}.");
|
|
}
|
|
return true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Console.WriteLine("Your input was not a valid input, an example of a valid input would be 100 or 100.00.");
|
|
}
|
|
Console.Write("Enter new rate: ");
|
|
return false;
|
|
}
|
|
|
|
if (Hotel.GetBaseRate() == null)
|
|
{
|
|
Console.Write("No base rate has been configured. " +
|
|
"You must set one for the current date.\n" +
|
|
"Enter new rate: ");
|
|
while (!SetRatePrompt(DateTime.Now.Date)) { }
|
|
}
|
|
else
|
|
{
|
|
Console.Write("What is the value of the rate you would like to set.\n" +
|
|
"Enter new rate: ");
|
|
while (!SetRatePrompt()) { }
|
|
}
|
|
}
|
|
void CheckIn()
|
|
{
|
|
string Email = GetGuestEmail();
|
|
TimeRefs? status = Hotel.CanBeCheckedIn(Email);
|
|
Guest? g = Hotel.GetGuestByEmail(Email);
|
|
if (g == null)
|
|
{
|
|
Console.WriteLine("No guest with that email exists.");
|
|
return;
|
|
}
|
|
if (!status.HasValue)
|
|
{
|
|
Console.WriteLine("No reservation exists for this email.");
|
|
return;
|
|
}
|
|
|
|
if (status.Value == TimeRefs.OnTime)
|
|
{
|
|
int? RoomID = Hotel.CheckInGuest(Email, DateTime.Now.Date);
|
|
if (RoomID != null)
|
|
{
|
|
Console.WriteLine($"Guest has been checked in, their room number is {RoomID}.");
|
|
}
|
|
}
|
|
else if (status.Value == TimeRefs.Late)
|
|
{
|
|
Console.WriteLine("Since the reservation was not checked in on the date scheduled, it has been cancelled. The guest will be charged the \"no show\" penalty.");
|
|
Reservation? r = Hotel.GetResByGuest(g);
|
|
|
|
if (r == null)
|
|
{
|
|
throw new Exception();
|
|
}
|
|
|
|
r.CancelReservation();
|
|
|
|
}
|
|
else if (status.Value == TimeRefs.Early)
|
|
{
|
|
Console.WriteLine("Since the reservation was not checked in on the date scheduled, it has been cancelled. The guest will be charged the \"no show\" penalty.");
|
|
}
|
|
return;
|
|
}
|
|
void CheckOut()
|
|
{
|
|
string Email = GetGuestEmail();
|
|
if (Hotel.GuestCurrentlyCheckedIn(Email))
|
|
{
|
|
Reservation r = Hotel.GetResByGuest(Hotel.GetGuestByEmail(Email));
|
|
if (r.Type == ReservationType.Incentive || r.Type == ReservationType.Conventional)
|
|
{
|
|
r.Transaction.Pay(r.Transaction.Owed, r.Guest.CreditCard);
|
|
}
|
|
|
|
Hotel.CheckOutGuest(Email, DateTime.Now.Date);
|
|
Console.WriteLine($"Guest has been checked out.");
|
|
}
|
|
else
|
|
{
|
|
Console.WriteLine($"Can't checkout a guest that hasn't been checked in.");
|
|
}
|
|
return;
|
|
}
|
|
void NotifyOutstandingPayments()
|
|
{
|
|
List<Reservation> activeSixtyRes = Hotel.GetActiveSixtyDayRes();
|
|
foreach (Reservation r in activeSixtyRes)
|
|
{
|
|
int days = (int)(r.StartDate.Date - DateTime.Now.Date).TotalDays - 30;
|
|
if (days < 0)
|
|
{
|
|
r.CancelReservation();
|
|
}
|
|
else if (days <= 15)
|
|
{
|
|
Email e = new(r.Guest.Email);
|
|
e.Send();
|
|
}
|
|
}
|
|
if (File.Exists("Emails.txt"))
|
|
{
|
|
FileInfo f = new("Emails.txt");
|
|
Console.WriteLine($"Emails have been written and appended to {f.FullName}");
|
|
}
|
|
}
|
|
void GenerateManagementReports()
|
|
{
|
|
var w = Hotel.GetExpectedOccupancyCount();
|
|
Management.CalculateExpectedOccupancy(w.Item2, w.Item1);
|
|
if (File.Exists("ExpectedOccupancy.txt"))
|
|
{
|
|
FileInfo f = new("ExpectedOccupancy.txt");
|
|
Console.WriteLine($"Expected occupancy has been written and appended to {f.FullName}");
|
|
}
|
|
var x = Hotel.GetExpectedIncomeCount();
|
|
Management.CalculateExpectedIncome(x.Item1, x.Item2, x.Item3);
|
|
if (File.Exists("ExpectedIncome.txt"))
|
|
{
|
|
FileInfo f = new("ExpectedIncome.txt");
|
|
Console.WriteLine($"Expected income has been written and appended to {f.FullName}");
|
|
}
|
|
var y = Hotel.GetIncentiveTransactions();
|
|
Management.CalculateIncentiveLosses(y.Item3, y.Item1, y.Item2);
|
|
if (File.Exists("IncentiveLosses.txt"))
|
|
{
|
|
FileInfo f = new("IncentiveLosses.txt");
|
|
Console.WriteLine($"Incentive losses have been written and appended to {f.FullName}");
|
|
}
|
|
}
|
|
void GenerateAccommodationBills()
|
|
{
|
|
List<Reservation> reservations = Hotel.GetDailyArrivals();
|
|
Accommodation.GenerateAccommodationBills(reservations);
|
|
|
|
if (File.Exists("AccommodationBills.txt"))
|
|
{
|
|
FileInfo f = new("AccommodationBills.txt");
|
|
Console.WriteLine($"Accommodation bills have been written and appended to {f.FullName}");
|
|
}
|
|
}
|
|
void GenerateOperationalReports()
|
|
{
|
|
List<Reservation> reservations = Hotel.GetDailyArrivals();
|
|
Operational.FetchDailyArriavals(reservations);
|
|
if (File.Exists("DailyArrivals.txt"))
|
|
{
|
|
FileInfo f = new("DailyArrivals.txt");
|
|
Console.WriteLine($"Daily arrivals have been written and appended to {f.FullName}");
|
|
}
|
|
var x = Hotel.GetDailyOccupancy();
|
|
Operational.FetchDailyOccupancy(x.Item1, x.Item2);
|
|
if (File.Exists("DailyOccupancy.txt"))
|
|
{
|
|
FileInfo f = new("DailyOccupancy.txt");
|
|
Console.WriteLine($"Daily occupancy has been written and appended to {f.FullName}");
|
|
}
|
|
}
|
|
void IssuePenalties()
|
|
{
|
|
List<Reservation> reservations = Hotel.GetPastDueReservations();
|
|
foreach (Reservation reservation in reservations)
|
|
{
|
|
reservation.CancelReservation();
|
|
}
|
|
Console.WriteLine("Penalties have been issued.");
|
|
}
|
|
|
|
Console.Write(
|
|
"\nWelcome to the Ophelias Oasis Hotel Management 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 "generate management report": GenerateManagementReports(); break;
|
|
case "generate operational report": GenerateOperationalReports(); break;
|
|
case "generate accommodation bills": GenerateAccommodationBills(); break;
|
|
case "notify pending payments": NotifyOutstandingPayments(); break;
|
|
case "issue penalties": IssuePenalties(); break;
|
|
case "checkin guest": CheckIn(); break;
|
|
case "checkout guest": CheckOut(); break;
|
|
case "set rate": SetFutureBaseRate(); break;
|
|
case "Q": return;
|
|
case "q": return;
|
|
default: Console.WriteLine("Unknown command, enter help for more inforamtion."); break;
|
|
}
|
|
Console.Write("\nCommand: ");
|
|
}
|
|
|
|
}
|
|
|
|
private static void Main()
|
|
{
|
|
if (!File.Exists("database.sqlite3") || new FileInfo("database.sqlite3").Length == 0)
|
|
{
|
|
/*
|
|
* Checks to see if the databse is created. If the database file is missing, that means
|
|
* it has not been initialized. Upon the initialization process, the tables are created
|
|
* and the rooms table is populated with 45 rooms. This is a preconfigured value within
|
|
* the InitializeRoomsTable() function since there was no requirement to make this configurable.
|
|
*/
|
|
SQLiteConnection.CreateFile("database.sqlite3");
|
|
using Database Manager = new();
|
|
Manager.InitializeTables();
|
|
Manager.InitializeRoomsTable();
|
|
}
|
|
if (!Hotel.CheckBaseRate())
|
|
{
|
|
// Checks to see if the base rate is configured, if not a warning will be shown.
|
|
Console.WriteLine("No base rate is configured. As a result reservations cannot be made until one is configured.");
|
|
}
|
|
|
|
bool run = true;
|
|
while (run)
|
|
{
|
|
// Main loop for checking if the person is a customer or employee.
|
|
Console.Write(
|
|
"Are you an employee or customer?\n" +
|
|
"1. Employee\n" +
|
|
"2. Customer/ Guest\n" +
|
|
": "
|
|
);
|
|
switch (Console.ReadLine().ToUpper()) // Using .ToUpper() to support "q" without having to write a case for it.
|
|
{
|
|
case "1": AdminMode(); break; // Enter employee (administrative) mode
|
|
case "2": GuestMode(); break; // Enter guest (customer) mode
|
|
case "Q": run = false; break; // Quit
|
|
default: Console.WriteLine("You must either specify 1 for Employee, 2 for Customer/ Guest, or Q to quit.\n\n"); break;
|
|
}
|
|
}
|
|
Console.WriteLine("Shutting system down.");
|
|
}
|
|
} |