diff --git a/OpheliasOasis/Managers/DatabaseManager.cs b/OpheliasOasis/Managers/DatabaseManager.cs index ec768a6..ef9649b 100644 --- a/OpheliasOasis/Managers/DatabaseManager.cs +++ b/OpheliasOasis/Managers/DatabaseManager.cs @@ -37,7 +37,7 @@ namespace Ophelias.Managers CREATE TABLE IF NOT EXISTS [reservations] ( [ID] INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, [RoomNum] INTEGER NULL UNIQUE, - [GuestID] INTEGER NOT NULL UNIQUE, + [GuestID] INTEGER NOT NULL, [TransactionID] INTEGER NOT NULL UNIQUE, [IsNoShow] BOOLEAN NOT NULL CHECK ([IsNoShow] IN (0,1)), [Type] INTEGER NOT NULL CHECK ([Type] IN (0,1,2,3)), diff --git a/OpheliasOasis/Managers/HotelManager.cs b/OpheliasOasis/Managers/HotelManager.cs index cd98936..39010ac 100644 --- a/OpheliasOasis/Managers/HotelManager.cs +++ b/OpheliasOasis/Managers/HotelManager.cs @@ -48,9 +48,10 @@ namespace Ophelias.Managers } return Occupancies; } - internal static int AvgOccupancySpan(DateTime Start, DateTime End) + internal static (int, bool) AvgOccupancySpan(DateTime Start, DateTime End) { int thirtyDayOcc = 0; + bool maxCapacityInRange = false; int days = (int)(End.Date - Start.Date).TotalDays; using (DatabaseManager Manager = new DatabaseManager()) { @@ -61,19 +62,26 @@ namespace Ophelias.Managers cmd.CommandText = $@"SELECT COUNT(*) FROM reservations WHERE DATE(@Date) - BETWEEN StartDate AND EndDate;"; - cmd.ExecuteNonQuery(); + BETWEEN @Start AND @End;"; cmd.Parameters.AddWithValue("@Date", Start.AddDays(i).Date.ToString("yyyy-MM-dd")); + cmd.Parameters.AddWithValue("@Start", Start); + cmd.Parameters.AddWithValue("@End", End); + cmd.ExecuteNonQuery(); + using (SQLiteDataReader reader = cmd.ExecuteReader()) { reader.Read(); - if(reader.HasRows) + if (reader.HasRows) + { thirtyDayOcc += reader.GetInt32(0); + if (reader.GetInt32(0) == 45) + maxCapacityInRange = true; + } } } } } - return thirtyDayOcc / days; + return (thirtyDayOcc / days, maxCapacityInRange); } internal static Guest? GetGuestByEmail(string Email) { @@ -104,7 +112,7 @@ namespace Ophelias.Managers } return g; } - internal static Reservation? GetResByGuestAndDate(Guest g) + internal static Reservation? GetResByGuest(Guest g) { Reservation? r = null; Transaction? t; @@ -152,6 +160,35 @@ namespace Ophelias.Managers } return r; } + internal static TimeRefs? CanBeCheckedIn(string Email) + { + TimeRefs? status = null; + using (DatabaseManager Manager = new DatabaseManager()) + { + using (SQLiteCommand cmd = Manager.con.CreateCommand()) + { + cmd.CommandText = $"SELECT * FROM reservation WHERE Email = @Email AND Status IN (0,1)"; + cmd.Parameters.AddWithValue("@Email", Email); + cmd.ExecuteNonQuery(); + using (SQLiteDataReader reader = cmd.ExecuteReader()) + { + reader.Read(); + if (reader.HasRows) + { + DateTime dt = reader.GetDateTime(8); + if (dt.Date == DateTime.Now.Date) + status = TimeRefs.OnTime; + else if (dt.Date > DateTime.Now.Date) + status = TimeRefs.Late; + else if (dt.Date < DateTime.Now.Date) + status = TimeRefs.Early; + } else + status = null; + } + } + } + return status; + } internal static double? GetBaseRate() { double? rate; @@ -174,6 +211,29 @@ namespace Ophelias.Managers } return rate; } + internal static bool GetBaseRateByDate(DateTime dt) + { + bool configured; + using (DatabaseManager Manager = new DatabaseManager()) + { + using (SQLiteCommand cmd = Manager.con.CreateCommand()) + { + string query = "SELECT Rate FROM rates WHERE DateSet = @Date;"; + cmd.CommandText = query; + cmd.Parameters.AddWithValue("@Date", dt.ToString("yyyy-MM-dd")); + cmd.ExecuteNonQuery(); + using (SQLiteDataReader reader = cmd.ExecuteReader()) + { + reader.Read(); + if (reader.HasRows) + configured = true; + else + configured = false; + } + } + } + return configured; + } internal static void SetBaseRate(double Rate, DateTime DateSet) { double rate; @@ -184,7 +244,22 @@ namespace Ophelias.Managers string query = $"INSERT INTO rates (Rate, DateSet) VALUES (@Rate, @DateSet);"; cmd.CommandText = query; cmd.Parameters.AddWithValue("@Rate", Rate); - cmd.Parameters.AddWithValue("@DateSet", DateSet); + cmd.Parameters.AddWithValue("@DateSet", DateSet.ToString("yyyy-MM-dd")); + cmd.ExecuteNonQuery(); + } + } + } + internal static void UpdateBaseRate(double Rate, DateTime DateSet) + { + double rate; + using (DatabaseManager Manager = new DatabaseManager()) + { + using (SQLiteCommand cmd = Manager.con.CreateCommand()) + { + string query = $"UPDATE rates SET rate = @Rate WHERE DateSet = @Date;"; + cmd.CommandText = query; + cmd.Parameters.AddWithValue("@Rate", Rate); + cmd.Parameters.AddWithValue("@Date", DateSet.ToString("yyyy-MM-dd")); cmd.ExecuteNonQuery(); } } @@ -231,13 +306,119 @@ namespace Ophelias.Managers } } } - internal static int CheckInGuest(DateTime CheckIn) + internal static int? CheckInGuest(string Email, DateTime CheckIn) { - return 1; + int? RoomID = null; + using (DatabaseManager Manager = new DatabaseManager()) + { + using (SQLiteTransaction Transaction = Manager.con.BeginTransaction()) + { + using (SQLiteCommand cmd = Manager.con.CreateCommand()) + { + cmd.CommandText = "UPDATE reservations SET RoomNum = (SELECT ID FROM rooms WHERE Occupied = 0 LIMIT 1), CheckIn = @Date " + + "WHERE GuestID = (SELECT ID FROM guests WHERE Email = @Email) AND RoomNum IS NULL AND Status in (@SActive,@SChanged);"; + cmd.Parameters.AddWithValue("@Email", Email); + cmd.Parameters.AddWithValue("@SActive", (int)ReservationStatus.Active); + cmd.Parameters.AddWithValue("@SChanged", (int)ReservationStatus.Changed); + cmd.Parameters.AddWithValue("@Date", CheckIn.ToString("yyyy-MM-dd")); + cmd.ExecuteNonQuery(); + } + using (SQLiteCommand cmd = Manager.con.CreateCommand()) + { + cmd.CommandText = "UPDATE rooms SET Occupied = 1 " + + "WHERE ID = (SELECT RoomNum FROM reservations WHERE GuestID = (SELECT ID FROM guests WHERE Email = @Email AND Status in (@SActive,@SChanged))));"; + cmd.Parameters.AddWithValue("@Email", Email); + cmd.Parameters.AddWithValue("@SActive", (int)ReservationStatus.Active); + cmd.Parameters.AddWithValue("@SChanged", (int)ReservationStatus.Changed); + cmd.ExecuteNonQuery(); + } + using (SQLiteCommand cmd = Manager.con.CreateCommand()) + { + cmd.CommandText = "SELECT RoomNum FROM reservations WHERE GuestID = (SELECT ID FROM guests WHERE Email = @Email AND Status in (@SActive,@SChanged))"; + cmd.Parameters.AddWithValue("@Email", Email); + cmd.Parameters.AddWithValue("@SActive", (int)ReservationStatus.Active); + cmd.Parameters.AddWithValue("@SChanged", (int)ReservationStatus.Changed); + cmd.ExecuteNonQuery(); + using (SQLiteDataReader reader = cmd.ExecuteReader()) + { + reader.Read(); + if (reader.HasRows) + { + RoomID = (int)reader.GetValue(0); + } + } + } + Transaction.Commit(); + } + } + return RoomID; } - internal static int CheckOutGuest(DateTime CheckOut) + internal static bool GuestCurrentlyCheckedIn(string Email) { - return 1; + bool EntryFound; + using (DatabaseManager Manager = new DatabaseManager()) + { + using (SQLiteCommand cmd = Manager.con.CreateCommand()) + { + cmd.CommandText = "SELECT * FROM reservations " + + "WHERE GuestID = (SELECT ID FROM guests WHERE Email = @Email AND Status in (@SActive,@SChanged)) AND CheckIn IS NOT NULL"; + cmd.Parameters.AddWithValue("@Email", Email); + cmd.Parameters.AddWithValue("@SActive", (int)ReservationStatus.Active); + cmd.Parameters.AddWithValue("@SChanged", (int)ReservationStatus.Changed); + cmd.ExecuteNonQuery(); + using (SQLiteDataReader reader = cmd.ExecuteReader()) + { + reader.Read(); + if (reader.HasRows) + EntryFound = true; + else + EntryFound = false; + } + } + } + return EntryFound; + } + internal static void CheckOutGuest(string Email, DateTime CheckOut) + { + using (DatabaseManager Manager = new DatabaseManager()) + { + using (SQLiteTransaction Transaction = Manager.con.BeginTransaction()) + { + using (SQLiteCommand cmd = Manager.con.CreateCommand()) + { + cmd.CommandText = "UPDATE rooms SET Occupied = 0 " + + "WHERE ID = (SELECT RoomNum FROM reservations WHERE GuestID = (SELECT ID FROM guests WHERE Email = @Email AND Status in (@SActive,@SChanged)));"; + cmd.Parameters.AddWithValue("@Email", Email); + cmd.Parameters.AddWithValue("@SActive", (int)ReservationStatus.Active); + cmd.Parameters.AddWithValue("@SChanged", (int)ReservationStatus.Ended); + cmd.ExecuteNonQuery(); + } + using (SQLiteCommand cmd = Manager.con.CreateCommand()) + { + cmd.CommandText = "UPDATE reservations SET RoomNum = NULL, CheckOut = @Date, Status = @Status " + + "WHERE GuestID = (SELECT ID FROM guests WHERE Email = @Email) AND RoomNum IS NOT NULL AND Status in (@SActive,@SChanged);"; + cmd.Parameters.AddWithValue("@Email", Email); + cmd.Parameters.AddWithValue("@Status", (int)ReservationStatus.Ended); + cmd.Parameters.AddWithValue("@SActive", (int)ReservationStatus.Active); + cmd.Parameters.AddWithValue("@SChanged", (int)ReservationStatus.Changed); + cmd.Parameters.AddWithValue("@Date", CheckOut.ToString("yyyy-MM-dd")); + cmd.ExecuteNonQuery(); + } + Transaction.Commit(); + } + } + return; + } + internal static List GetActiveSixtyDayRes() + { + List list = new List(); + return list; } } + internal enum TimeRefs + { + OnTime, + Early, + Late + } } diff --git a/OpheliasOasis/Models/Reservation.cs b/OpheliasOasis/Models/Reservation.cs index 9570da4..c312430 100644 --- a/OpheliasOasis/Models/Reservation.cs +++ b/OpheliasOasis/Models/Reservation.cs @@ -46,7 +46,7 @@ namespace Ophelias.Models Transaction Transaction = new Transaction( Rate: (double)BaseRate, - Owed: TxFunctions.CalculateOwed((double)BaseRate, (int)(EndDate.Date - StartDate.Date).TotalDays), + Owed: TxFunctions.CalculateOwed((double)BaseRate, (int)(EndDate.Date - StartDate.Date).TotalDays, Multiplier), Multiplier: Multiplier, PayBy: TxFunctions.GetPayByDate(Type, StartDate, EndDate) ); @@ -179,7 +179,7 @@ namespace Ophelias.Models { Conventional, Prepaid, - Incentive, SixtyDayAdvance, + Incentive, } } diff --git a/OpheliasOasis/Models/Transaction.cs b/OpheliasOasis/Models/Transaction.cs index d1c0e03..f9ccc7e 100644 --- a/OpheliasOasis/Models/Transaction.cs +++ b/OpheliasOasis/Models/Transaction.cs @@ -161,7 +161,7 @@ namespace Ophelias.Models internal static double IncentiveFee(DateTime Start, DateTime End) { int thirtyDayOcc; - thirtyDayOcc = HotelManager.AvgOccupancySpan(Start, End); + (thirtyDayOcc, _) = HotelManager.AvgOccupancySpan(Start, End); if ((double)(thirtyDayOcc / 45.0) <= 0.6) return 0.80; return 1.0; @@ -177,9 +177,9 @@ namespace Ophelias.Models default: throw new NotImplementedException(); } } - internal static double CalculateOwed(double Rate, int Days) + internal static double CalculateOwed(double Rate, int Days, double Multiplier) { - return Rate * Days; + return Rate * Days * Multiplier; } diff --git a/OpheliasOasis/Program.cs b/OpheliasOasis/Program.cs index 777295f..bbda8b8 100644 --- a/OpheliasOasis/Program.cs +++ b/OpheliasOasis/Program.cs @@ -5,6 +5,19 @@ using System.Data.SQLite; 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; @@ -78,18 +91,6 @@ class Program } 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: "); @@ -107,7 +108,7 @@ class Program return; } Console.WriteLine($"\nYou have logged into {activeGuest.FirstName} {activeGuest.LastName} ({email})."); - activeReservation = HotelManager.GetResByGuestAndDate(activeGuest); + activeReservation = HotelManager.GetResByGuest(activeGuest); } void CreateNewGuestPrompt() { @@ -216,44 +217,113 @@ class Program break; Console.Write("Please enter either 1, 2, 3, or 4: "); } - return (ReservationType)Convert.ToInt32(input); + return (ReservationType)(Convert.ToInt32(input) - 1); } - (DateTime, DateTime) SelectDate() + bool CheckReservationRestrictions(DateTime Date, ReservationType Type) { - 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) + if (Type == ReservationType.Prepaid) { - 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): "); + if ((Date - DateTime.Now).TotalDays < 90) + { + Console.WriteLine("Prepaid reservations must be made 90 days in advance."); + } else - Console.Write("Please enter a valid date (2021-12-31): "); + { + return true; + } } - return (_StartDate.Date, _EndDate.Date); + else if (Type == ReservationType.SixtyDayAdvance) + { + if ((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) = HotelManager.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; + DateTime? NewStartDate = activeReservation.StartDate, NewEndDate = activeReservation.EndDate; ReservationType NewType = activeReservation.Type; bool completed = false; @@ -269,10 +339,18 @@ class Program { case "Q": Console.WriteLine("Changes have has been deleted."); return; case "1": NewType = SelectReservation(); break; - case "2": (NewStartDate, NewEndDate) = SelectDate(); break; + case "2": (NewStartDate, NewEndDate) = SelectDate(NewType); break; case "S": - completed = true; - (activeReservation.Type, activeReservation.StartDate, activeReservation.EndDate) = (NewType, NewStartDate, NewEndDate); + 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; } @@ -299,11 +377,17 @@ class Program string input; ReservationType Type; - DateTime StartDate; - DateTime EndDate; + DateTime? StartDate; + DateTime? EndDate; Type = SelectReservation(); - (StartDate, EndDate) = SelectDate(); + (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" + @@ -316,31 +400,27 @@ class Program } 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" + + $"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 == "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") + if (input == "Q") { Console.WriteLine("Reservation has been deleted."); return; } else { - Console.WriteLine("Input must be YES, NO, or Q.\n: "); + Console.Write("Input must be YES or Q.\n: "); input = Console.ReadLine(); } } - activeReservation = new Reservation(activeGuest, Type, DateTime.Now.Date, StartDate, EndDate); + if (Type == ReservationType.Prepaid) + { + activeReservation = new Reservation(activeGuest, Type, DateTime.Now.Date, StartDate.Value, EndDate.Value); + activeReservation.Transaction.Pay(activeReservation.Transaction.Owed); + } Console.WriteLine("Your reservation has been made."); } void UpdateReservation() @@ -365,7 +445,7 @@ class Program { if (input == "NO") { - (_StartDate, _EndDate) = SelectDate(); + (_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" + @@ -449,7 +529,7 @@ class Program Console.Write("\nCommand: "); } } - private void AdminMode() + private static void AdminMode() { void help() { @@ -460,9 +540,11 @@ class Program "\tgenerate accomodation bills - Generates an accomodation 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" + - "\tbaserate set - Sets a new base rate to begin after a specified date.\n" + + "\tset rate - Sets a new base rate to begin after a specified date.\n" + "Enter Q to quit.\n" ); return; @@ -470,15 +552,148 @@ class Program 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) + { + HotelManager.SetBaseRate(Convert.ToDouble(amount), (DateTime)FixedDate); + Console.WriteLine($"A base rate of {amount} has been set and will take effect on {FixedDate.Value.ToString("yyyy-MM-dd")}."); + } 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 (HotelManager.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") + { + HotelManager.UpdateBaseRate(Convert.ToDouble(amount), StartDate.Date); + return true; + } + } else + { + break; + } + Console.Write("Please enter a valid date (2021-12-31): "); + } + HotelManager.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 (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 (!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 = HotelManager.CanBeCheckedIn(Email); + Guest? g = HotelManager.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 = HotelManager.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 = HotelManager.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 (HotelManager.GuestCurrentlyCheckedIn(Email)) + { + HotelManager.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; + } + + 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) { @@ -489,10 +704,11 @@ class Program 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 "notify pending payments": break; + case "issue penalties": break; + case "checkin guest": CheckIn(); break; + case "checkout guest": CheckOut(); break; + case "set rate": SetFutureBaseRate(); break; case "Q": return; default: Console.WriteLine("Unknown command, enter help for more inforamtion."); break; } @@ -502,7 +718,7 @@ class Program } static void Main() { - + HotelManager.CheckBaseRate(); if (!File.Exists("database.sqlite3") || new FileInfo("database.sqlite3").Length == 0) { SQLiteConnection.CreateFile("database.sqlite3"); @@ -524,7 +740,7 @@ class Program ); switch(Console.ReadLine().ToUpper()) { - case "1": break; + case "1": AdminMode(); 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; diff --git a/OpheliasOasis/Reporting/Accomodation.cs b/OpheliasOasis/Reporting/Accomodation.cs new file mode 100644 index 0000000..47d1c82 --- /dev/null +++ b/OpheliasOasis/Reporting/Accomodation.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Ophelias.Reporting +{ + internal class Accomodation + { + } +} diff --git a/OpheliasOasis/Reporting/Email.cs b/OpheliasOasis/Reporting/Email.cs new file mode 100644 index 0000000..420ad0b --- /dev/null +++ b/OpheliasOasis/Reporting/Email.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Ophelias.Reporting +{ + internal class Email + { + } +} diff --git a/OpheliasOasis/Reporting/Management.cs b/OpheliasOasis/Reporting/Management.cs new file mode 100644 index 0000000..130eb3f --- /dev/null +++ b/OpheliasOasis/Reporting/Management.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Ophelias.Reporting +{ + internal class Management + { + } +} diff --git a/OpheliasOasis/Reporting/Operational.cs b/OpheliasOasis/Reporting/Operational.cs new file mode 100644 index 0000000..f62ef52 --- /dev/null +++ b/OpheliasOasis/Reporting/Operational.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Ophelias.Reporting +{ + internal class Operational + { + } +} diff --git a/OpheliasOasis/Validation.cs b/OpheliasOasis/Validation.cs index d7170cd..ea27f62 100644 --- a/OpheliasOasis/Validation.cs +++ b/OpheliasOasis/Validation.cs @@ -14,26 +14,31 @@ namespace Ophelias.Expressions internal static Regex CardRx = new Regex(@"^[0-9]{16}$", RegexOptions.Compiled); internal static Regex ExpriationRx = new Regex(@"^(0?[1-9]|1[012])/2[0-9]{1}$", RegexOptions.Compiled); internal static Regex CCVRx = new Regex(@"^[0-9]{3}$", RegexOptions.Compiled); + internal static Regex MoneyRx = new Regex(@"^(\d+\.\d{2}|\d+)$", RegexOptions.Compiled); } internal static class Validation { internal static bool ValidateCreditCard(string CreditCard) { - if (Expressions.CardRx.IsMatch(CreditCard)) - return true; - return false; + return Expressions.CardRx.IsMatch(CreditCard); } internal static bool ValidateExpirationDate(string Expiration) { if (Expressions.ExpriationRx.IsMatch(Expiration)) { DateTime dt = DateTime.ParseExact(Expiration, "MM/yy", CultureInfo.InvariantCulture); - if (dt.Year >= DateTime.Now.Year) - if (dt.Month >= DateTime.Now.Month) - return true; + if (dt.Date >= DateTime.Now.Date) + return true; } return false; } + internal static bool ValidateExpirationNotBeforeReservation(string Expiration, DateTime CollectionDate) + { + DateTime dt = DateTime.ParseExact(Expiration, "MM/yy", CultureInfo.InvariantCulture); + if (dt.Date > CollectionDate.Date) + return true; + return false; + } internal static bool ValidateEmail(string email) { EmailAddressAttribute EmailChecker = new EmailAddressAttribute(); @@ -45,5 +50,10 @@ namespace Ophelias.Expressions return true; return false; } + internal static bool ValidateMoney(string Money) + { + return Expressions.MoneyRx.IsMatch(Money); + } + } }