diff --git a/OpheliasOasis/Managers/DatabaseManager.cs b/OpheliasOasis/Managers/DatabaseManager.cs index 253eca7..06c774a 100644 --- a/OpheliasOasis/Managers/DatabaseManager.cs +++ b/OpheliasOasis/Managers/DatabaseManager.cs @@ -31,6 +31,7 @@ namespace Ophelias.Managers [Multiplier] INTEGER NOT NULL, [RefundAmount] INTEGER NOT NULL, [PayBy] TEXT NOT NULL, + [LastPaid] TEXXT NULL, [PaidOn] TEXT NULL); CREATE TABLE IF NOT EXISTS [reservations] ( @@ -55,8 +56,8 @@ namespace Ophelias.Managers [ID] INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, [Fname] TEXT NOT NULL, [Lname] TEXT NOT NULL, - [Email] TEXT NOT NULL, - [CreditCard] TEXT NULL, + [Email] TEXT NOT NULL UNIQUE, + [CreditCard] TEXT NULL UNIQUE, [Expiration] TEXT NULL, [CCV] TEXT NULL); @@ -67,7 +68,8 @@ namespace Ophelias.Managers CREATE TABLE IF NOT EXISTS [rates] ( [ID] INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, [Rate] INTEGER NOT NULL, - [DateSet] TEXT NOT NULL);"; + [DateSet] TEXT NOT NULL UNIQUE, + [DefaultRate] INTEGER NULL UNIQUE CHECK ([DefaultRate] IN (1)));"; using (SQLiteCommand cmd = con.CreateCommand()) { @@ -103,10 +105,10 @@ namespace Ophelias.Managers internal static class QueryBuilder { - internal static string? UpdateTransaction(int id, + internal static string? UpdateTransaction(int Id, double? Rate = null, double? Owed = null, double? Penalty = null, double? Multiplier = null, double? Refund = null, - DateTime? PayBy = null, DateTime? PaidOn = null) + DateTime? PayBy = null, DateTime? LastPaid = null, DateTime? PaidOn = null) { List queryComponents = new List(); string query = "UPDATE transactions SET"; @@ -122,82 +124,110 @@ namespace Ophelias.Managers if (Refund.HasValue) queryComponents.Add($"Refund = {Refund}"); if (PayBy.HasValue) - queryComponents.Add($"PaidBy = {PayBy.Value.ToString("yyyy-MM-dd")}"); + queryComponents.Add($"PayBy = {PayBy.Value.Date.ToString("yyyy-MM-dd")}"); + if (LastPaid.HasValue) + queryComponents.Add($"LastPaid = {LastPaid.Value.Date.ToString("yyyy-MM-dd")}"); if (PaidOn.HasValue) - queryComponents.Add($"PaidOn = {PaidOn.Value.ToString("yyyy-MM-dd")}"); + queryComponents.Add($"PaidOn = {PaidOn.Value.Date.ToString("yyyy-MM-dd")}"); - if (queryComponents.Count == 0) - query += " " + string.Join(", ", queryComponents) + " " + $"WHERE ID = {id};"; + if (queryComponents.Count > 0) + query += " " + string.Join(", ", queryComponents) + " " + $"WHERE ID = {Id};"; else return null; return query; } - internal static string? UpdateReservation(int id, - int? roomid = null, int? guestid = null, int? transactionid = null, bool? isnoshow = null, ReservationType? type = null, - ReservationStatus? status = null, DateTime? creationdate = null, DateTime? startdate = null, DateTime? enddate = null, - DateTime? checkin = null, DateTime? checkout = null, DateTime? datechanged = null) + internal static string? UpdateReservation(int Id, + int? RoomID = null, int? GuestID = null, int? TransactionID = null, bool? IsNoShow = null, ReservationType? Type = null, + ReservationStatus? Status = null, DateTime? CreationDate = null, DateTime? StartDate = null, DateTime? EndDate = null, + DateTime? CheckIn = null, DateTime? CheckOut = null, DateTime? DateChanged = null) { - List queryComponents = new List(); + List QueryParts = new List(); string query = "UPDATE reservations SET"; - if (roomid.HasValue) - queryComponents.Add($"RoomID = {roomid}"); - if (guestid.HasValue) - queryComponents.Add($"GuestID = {guestid}"); - if (transactionid.HasValue) - queryComponents.Add($"TransactionID = {transactionid}"); - if (isnoshow.HasValue) - queryComponents.Add($"IsNoShow = {Convert.ToInt32(isnoshow)}"); - if (type.HasValue) - queryComponents.Add($"Type = {(int)type}"); - if (status.HasValue) - queryComponents.Add($"Type = {(int)status}"); - if (creationdate.HasValue) - queryComponents.Add($"CreationDate = {creationdate.Value.ToString("yyyy-MM-dd")}"); - if (startdate.HasValue) - queryComponents.Add($"StartDate = {startdate.Value.ToString("yyyy-MM-dd")}"); - if (enddate.HasValue) - queryComponents.Add($"EndDate = {enddate.Value.ToString("yyyy-MM-dd")}"); - if (checkin.HasValue) - queryComponents.Add($"CheckIn = {checkin.Value.ToString("yyyy-MM-dd")}"); - if (checkout.HasValue) - queryComponents.Add($"CheckOut = {checkout.Value.ToString("yyyy-MM-dd")}"); - if (datechanged.HasValue) - queryComponents.Add($"CheckOut = {datechanged.Value.ToString("yyyy-MM-dd")}"); + if (RoomID.HasValue) + QueryParts.Add($"RoomID = {RoomID}"); + if (GuestID.HasValue) + QueryParts.Add($"GuestID = {GuestID}"); + if (TransactionID.HasValue) + QueryParts.Add($"TransactionID = {TransactionID}"); + if (IsNoShow.HasValue) + QueryParts.Add($"IsNoShow = {Convert.ToInt32(IsNoShow)}"); + if (Type.HasValue) + QueryParts.Add($"Type = {(int)Type}"); + if (Status.HasValue) + QueryParts.Add($"Status = {(int)Status}"); + if (CreationDate.HasValue) + QueryParts.Add($"CreationDate = {CreationDate.Value.Date.ToString("yyyy-MM-dd")}"); + if (StartDate.HasValue) + QueryParts.Add($"StartDate = {StartDate.Value.Date.ToString("yyyy-MM-dd")}"); + if (EndDate.HasValue) + QueryParts.Add($"EndDate = {EndDate.Value.Date.ToString("yyyy-MM-dd")}"); + if (CheckIn.HasValue) + QueryParts.Add($"CheckIn = {CheckIn.Value.Date.ToString("yyyy-MM-dd")}"); + if (CheckOut.HasValue) + QueryParts.Add($"CheckOut = {CheckOut.Value.Date.ToString("yyyy-MM-dd")}"); + if (DateChanged.HasValue) + QueryParts.Add($"DateChanged = {DateChanged.Value.Date.ToString("yyyy-MM-dd")}"); - if (queryComponents.Count == 0) - query += " " + string.Join(", ", queryComponents) + " " + $"WHERE ID = {id};"; + if (QueryParts.Count > 0) + query += " " + string.Join(", ", QueryParts) + " " + $"WHERE ID = {Id};"; else return null; return query; } - internal static string CreateTransaction(double Rate, double Owed, double Penalty, - double Multiplier, double Refund, bool isLate, - bool PaidOff, DateTime PaidBy, DateTime? PaidOn = null) + internal static string CreateTransaction(double Rate, double Owed, + double Multiplier, DateTime PayBy, DateTime? LastPaid = null, + DateTime? PaidOn = null, double Refund = 0, double Penalty = 0) { - return @$"INSERT INTO transactions (Rate, Owed, Penalty, Multiplier, Refund, IsLate, PaidOff, PaidBy, PaidOn) - VALUES ({Rate}, {Owed}, {Penalty}, {Multiplier}, {Refund}, {isLate}, {PaidOff}, {PaidBy}, {PaidOn});"; + return @$"INSERT INTO transactions (Rate, Owed, Penalty, Multiplier, RefundAmount, PayBy, LastPaid, PaidOn) + VALUES ({Rate}, {Owed}, {Penalty}, {Multiplier}, {Refund}, {PayBy}, {PayBy}, {PaidOn});"; } - internal static string CreateReservation(int roomid, int guestid, int transactionid, bool isnoshow, ReservationType type, + internal static string CreateReservation(int guestid, int transactionid, ReservationType type, ReservationStatus status, DateTime creationdate, DateTime startdate, DateTime enddate, - DateTime checkin, DateTime checkout, DateTime datechanged) + DateTime? checkin = null, DateTime? checkout = null, DateTime? datechanged = null, bool? isnoshow = false) { - return @$"INSERT INTO reservations (RoomID, GuestID, TransactionID, IsNoShow, Type, Status, CreationDate, StartDate, EndDate, CheckIn, CheckOut, DateChanged) - VALUES ({roomid}, {guestid}, {transactionid}, {isnoshow}, {status}, {creationdate}, {startdate}, {enddate}, {checkin}, {checkout}, {datechanged});"; + return @$"INSERT INTO reservations (GuestID, TransactionID, IsNoShow, Type, Status, CreationDate, StartDate, EndDate, CheckIn, CheckOut, DateChanged) + VALUES ({guestid}, {transactionid}, {isnoshow}, {status}, {creationdate}, {startdate}, {enddate}, {checkin}, {checkout}, {datechanged});"; } internal static string CreateGuest(string FirstName, string LastName, string Email, string? CreditCard, string? Expiration, string? CCV) { if (CreditCard != null && Expiration != null && CCV != null) - return $@"INSERT INTO guests (Fname, Lname, Email) VALUES ({FirstName}, {LastName}, {Email});"; + return $@"INSERT INTO guests (Fname, Lname, Email, CreditCard, Expiration, CCV) VALUES ('{FirstName}', '{LastName}', '{Email}', '{CreditCard}', '{Expiration}', '{CCV}');"; else - return $@"INSERT INTO guests (Fname, Lname, Email, CreditCard, Expiration, CCV) VALUES ({FirstName}, {LastName}, {Email}, {CreditCard}, {Expiration}, {CCV});"; + return $@"INSERT INTO guests (Fname, Lname, Email) VALUES ('{FirstName}', '{LastName}', '{Email}');"; + } + + internal static string? UpdateGuest(int Id, string? FirstName = null, string? LastName = null, string? Email = null, string? CreditCard = null, string? Expiration = null, string? CCV = null) + { + List QueryParts = new List(); + string query = "UPDATE guests SET"; + + if (!string.IsNullOrEmpty(FirstName)) + QueryParts.Add($"Fname = '{FirstName}'"); + if (!string.IsNullOrEmpty(LastName)) + QueryParts.Add($"Lname = '{LastName}'"); + if (!string.IsNullOrEmpty(LastName)) + QueryParts.Add($"Email = '{Email}'"); + if (!string.IsNullOrEmpty(CreditCard)) + QueryParts.Add($"CreditCard = '{CreditCard}'"); + if (!string.IsNullOrEmpty(Expiration)) + QueryParts.Add($"Expiration = '{Expiration}'"); + if (!string.IsNullOrEmpty(CCV)) + QueryParts.Add($"CCV = '{CCV}'"); + + if (QueryParts.Count > 0) + query += " " + string.Join(", ", QueryParts) + " " + $"WHERE ID = {Id};"; + else + return null; + + return query; } } } diff --git a/OpheliasOasis/Managers/HotelManager.cs b/OpheliasOasis/Managers/HotelManager.cs index cdd393a..e58df55 100644 --- a/OpheliasOasis/Managers/HotelManager.cs +++ b/OpheliasOasis/Managers/HotelManager.cs @@ -1,9 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Ophelias.Models; +using Ophelias.Models; using System.Data.SQLite; namespace Ophelias.Managers @@ -12,107 +7,117 @@ namespace Ophelias.Managers { internal static int GetLastId(string tableName) { - int lastId = 0; - using (DatabaseManager manager = new DatabaseManager()) - { - using (SQLiteCommand cmd = manager.con.CreateCommand()) - { - cmd.CommandText = $"SELECT SEQ FROM sqlite_sequence WHERE name=\"{tableName}\";"; - cmd.ExecuteNonQuery(); - using (SQLiteDataReader reader = cmd.ExecuteReader()) - { - reader.Read(); - lastId = reader.GetInt32(0); - } - } - } - return lastId; - } - internal static int GetThirtyDayOccupancy(DateTime start) - { - int thirtyDayOcc; - using (DatabaseManager Manager = new DatabaseManager()) - { - using (SQLiteCommand cmd = Manager.con.CreateCommand()) { - cmd.CommandText = $@"SELECT COUNT(*) - FROM reservations - WHERE StartDate => date({start.ToString("yyyy-MM-dd")}) - AND EndDate <= date({start.AddDays(30).ToString("yyyy-MM-dd")});"; - cmd.ExecuteNonQuery(); - using (SQLiteDataReader reader = cmd.ExecuteReader()) - { - reader.Read(); - thirtyDayOcc = reader.GetInt32(0); - } - } - } - - return thirtyDayOcc; - } - internal static int CreateReservation(int roomid, int guestid, int transactionid, bool isnoshow, ReservationType type, - ReservationStatus status, DateTime creationdate, DateTime startdate, DateTime enddate, - DateTime checkin, DateTime checkout, DateTime datechanged) - { - int id; + int LastId = 0; using (DatabaseManager Manager = new DatabaseManager()) { using (SQLiteCommand cmd = Manager.con.CreateCommand()) { - cmd.CommandText = QueryBuilder.CreateReservation(roomid, guestid, transactionid, isnoshow, type, - status, creationdate, startdate, enddate, - checkin, checkout, datechanged); + cmd.CommandText = $"SELECT SEQ FROM sqlite_sequence WHERE name='{tableName}';"; + cmd.ExecuteNonQuery(); + using (SQLiteDataReader reader = cmd.ExecuteReader()) + { + reader.Read(); + LastId = reader.GetInt32(0); + } + } + } + return LastId; + } + internal static List DailyOccupancies(DateTime Date) + { + List Occupancies = new List(); + using (DatabaseManager Manager = new DatabaseManager()) + { + using (SQLiteCommand cmd = Manager.con.CreateCommand()) + { + cmd.CommandText = $@"SELECT COUNT(*) + FROM reservations + WHERE DATE('{Date.Date.ToString("yyyy-MM-dd")}') + BETWEEN StartDate AND EndDate;"; + cmd.ExecuteNonQuery(); + using (SQLiteDataReader reader = cmd.ExecuteReader()) + { + reader.Read(); + Occupancies.Add(reader.GetInt32(0)); + } + } + } + return Occupancies; + } + internal static int AvgOccupancySpan(DateTime Start, DateTime End) + { + int thirtyDayOcc = 0; + int days = (int)(Start.Date - End.Date).TotalDays; + using (DatabaseManager Manager = new DatabaseManager()) + { + for (int i = 0; i < days; i++) + { + using (SQLiteCommand cmd = Manager.con.CreateCommand()) + { + cmd.CommandText = $@"SELECT COUNT(*) + FROM reservations + WHERE DATE('{Start.AddDays(i).Date.ToString("yyyy-MM-dd")}') + BETWEEN StartDate AND EndDate;"; + cmd.ExecuteNonQuery(); + using (SQLiteDataReader reader = cmd.ExecuteReader()) + { + reader.Read(); + thirtyDayOcc += reader.GetInt32(0); + } + } + } + } + return thirtyDayOcc / days; + } + internal static Reservation CreateReservation(Guest Guest, ReservationType Type, + DateTime CreationDate, DateTime StartDate, DateTime EndDate, ReservationStatus Status = ReservationStatus.Active) + { + int id; double Multiplier; + switch (Type) + { + case ReservationType.Conventional: Multiplier = TxFunctions.ConventionalFee; break; + case ReservationType.Prepaid: Multiplier = TxFunctions.PrepaidFee; break; + case ReservationType.Incentive: Multiplier = TxFunctions.IncentiveFee(StartDate, EndDate); break; + case ReservationType.SixtyDayAdvance: Multiplier = TxFunctions.SixtyDayFee; break; + default: throw new NotImplementedException(); + } + Transaction t = CreateTransaction( + Rate: GetBaseRate(), + Owed: TxFunctions.CalculateOwed(GetBaseRate(), (int)(StartDate.Date - EndDate.Date).TotalDays), + Multiplier: Multiplier, + PayBy: TxFunctions.GetPayByDate(Type, StartDate, EndDate) + ); + using (DatabaseManager Manager = new DatabaseManager()) + { + using (SQLiteCommand cmd = Manager.con.CreateCommand()) + { + cmd.CommandText = QueryBuilder.CreateReservation(Guest.Id, t.Id, Type, + Status, CreationDate, StartDate, EndDate); cmd.ExecuteNonQuery(); } id = (int)Manager.con.LastInsertRowId; } - return id; - } - internal static void ChangeReservationDates(Reservation r, Transaction t, DateTime start, DateTime end) - { - using (DatabaseManager Manager = new DatabaseManager()) - { - using (SQLiteCommand cmd = Manager.con.CreateCommand()) - { - string? query = QueryBuilder.UpdateReservation(id: r.Id, startdate: start, enddate: end, datechanged: DateTime.Now); - if (query == null) - throw new Exception(); - - query += QueryBuilder.UpdateTransaction(id: r.TransactionId, Multiplier: 1.1); - cmd.CommandText = query; - cmd.ExecuteNonQuery(); - } - } + return new Reservation(id, Guest, t, Type, Status, CreationDate, StartDate, EndDate); } - internal static Transaction CreateTransaction(double Rate, double Owed, double Penalty, - double Multiplier, double Refund, bool isLate, - bool PaidOff, DateTime PaidBy, DateTime? PaidOn = null) + internal static Transaction CreateTransaction(double Rate, double Owed, + double Multiplier, DateTime PayBy, DateTime? LastPaid = null, + DateTime? PaidOn = null, double Refund = 0, double Penalty = 0) { int Id; using (DatabaseManager Manager = new DatabaseManager()) { using (SQLiteCommand cmd = Manager.con.CreateCommand()) { - cmd.CommandText = QueryBuilder.CreateTransaction(Rate, Owed, Penalty, Multiplier, Refund, isLate, PaidOff, PaidBy, PaidOn); + cmd.CommandText = QueryBuilder.CreateTransaction(Rate, Owed, Multiplier, PayBy,Refund: Refund, Penalty: Penalty, LastPaid: LastPaid, PaidOn: PaidOn); cmd.ExecuteNonQuery(); } Id = (int)Manager.con.LastInsertRowId; } - return new Transaction(Id, Rate, Owed, Penalty, Multiplier, Refund, PaidBy, PaidOn); + return new Transaction(Id, Rate, Owed, Multiplier, Penalty: Penalty, RefundAmount: Refund, PayBy: PayBy, PaidOn: PaidOn); } - internal static int CheckInGuest(DateTime CheckIn) - { - return 1; - } - internal static int CheckOutGuest(DateTime CheckOut) - { - return 1; - } - internal static Guest CreateGuest(string FirstName, string LastName, string Email, string? CreditCard = null, string? Expiration = null, string? CCV = null) { - string query = QueryBuilder.CreateGuest(FirstName, LastName, Email, CreditCard, Expiration, CCV); - int Id; using (DatabaseManager Manager = new DatabaseManager()) { @@ -125,9 +130,127 @@ namespace Ophelias.Managers } if (CreditCard != null && Expiration != null && CCV != null) - return new Guest(FirstName, LastName, Email, CreditCard, Expiration, CCV); + return new Guest(Id, FirstName, LastName, Email, CreditCard, Expiration, CCV); else - return new Guest(FirstName, LastName, Email); + return new Guest(Id, FirstName, LastName, Email); + } + internal static void UpdateGuest(int Id, string? FirstName = null, string? LastName = null, string? Email = null, string? CreditCard = null, string? Expiration = null, string? CCV = null) + { + using (DatabaseManager Manager = new DatabaseManager()) + { + using (SQLiteCommand cmd = Manager.con.CreateCommand()) + { + cmd.CommandText = QueryBuilder.UpdateGuest(Id, FirstName, LastName, Email, CreditCard, Expiration, CCV); + cmd.ExecuteNonQuery(); + } + } + } + internal static Guest? GetGuestByEmail(string Email) + { + Guest? g = null; + using (DatabaseManager Manager = new DatabaseManager()) + { + using (SQLiteCommand cmd = Manager.con.CreateCommand()) + { + cmd.CommandText = $"SELECT * FROM guests WHERE email = '{Email}'"; + cmd.ExecuteNonQuery(); + using (SQLiteDataReader reader = cmd.ExecuteReader()) + { + reader.Read(); + if (reader.HasRows) + { + string? CreditCard = null, Expiration = null, CCV = null; + if (reader[4].GetType() != typeof(DBNull)) + CreditCard = reader[4].ToString(); + if (reader[5].GetType() != typeof(DBNull)) + Expiration = reader[5].ToString(); + if (reader[6].GetType() != typeof(DBNull)) + CCV = reader[6].ToString(); + g = new Guest(reader.GetInt32(0), reader.GetString(1), reader.GetString(2), reader.GetString(3), CreditCard, Expiration, CCV); + } + } + } + } + return g; + } + internal static double GetBaseRate() + { + double rate; + using (DatabaseManager Manager = new DatabaseManager()) + { + using (SQLiteCommand cmd = Manager.con.CreateCommand()) + { + string query = "SELECT Rate FROM rates WHERE DefaultRate = 1;"; + cmd.CommandText = query; + cmd.ExecuteNonQuery(); + using (SQLiteDataReader reader = cmd.ExecuteReader()) + { + reader.Read(); + rate = reader.GetDouble(0); + } + } + } + return rate; + } + internal static void SetBaseRate(double Rate, DateTime DateSet) + { + double rate; + using (DatabaseManager Manager = new DatabaseManager()) + { + using (SQLiteCommand cmd = Manager.con.CreateCommand()) + { + string query = $"INSERT INTO rates (Rate, DateSet) VALUES ({Rate}, {DateSet});"; + cmd.CommandText = query; + cmd.ExecuteNonQuery(); + } + } + } + internal static void CheckBaseRate() + { + using (DatabaseManager Manager = new DatabaseManager()) + { + int? OldId; + using (SQLiteCommand cmd = Manager.con.CreateCommand()) + { + string query = "SELECT Id FROM rates WHERE DefaultRate = 1;"; + cmd.CommandText = query; + cmd.ExecuteNonQuery(); + using (SQLiteDataReader reader = cmd.ExecuteReader()) + { + reader.Read(); + OldId = reader.GetInt32(0); + } + } + int? Id; + using (SQLiteCommand cmd = Manager.con.CreateCommand()) + { + string query = $"SELECT Id FROM rates WHERE DateSet = {DateTime.Now.Date.ToString("yyyy-MM-dd")};"; + cmd.CommandText = query; + cmd.ExecuteNonQuery(); + using (SQLiteDataReader reader = cmd.ExecuteReader()) + { + reader.Read(); + Id = reader.GetInt32(0); + } + } + if (Id != null) + { + using (SQLiteCommand cmd = Manager.con.CreateCommand()) + { + cmd.CommandText = $@"UPDATE rates SET DefaultRate = NULL WHERE Id = {OldId}; + UPDATE rates SET DefaultRate = 1 WHERE Id = {Id}"; + cmd.ExecuteNonQuery(); + } + } + } + } + internal static int CheckInGuest(DateTime CheckIn) + { + return 1; + } + internal static int CheckOutGuest(DateTime CheckOut) + { + return 1; } } } diff --git a/OpheliasOasis/Models/Guest.cs b/OpheliasOasis/Models/Guest.cs index 2fc8042..294b882 100644 --- a/OpheliasOasis/Models/Guest.cs +++ b/OpheliasOasis/Models/Guest.cs @@ -17,14 +17,9 @@ namespace Ophelias.Models internal string? CCV; internal string? Expiration; - internal Guest(string FirstName, string LastName, string Email) - { - this.FirstName = FirstName; - this.LastName = LastName; - this.Email = Email; - } - internal Guest(string FirstName, string LastName, string Email, string CreditCard, string Expiration, string CCV) + internal Guest(int Id, string FirstName, string LastName, string Email, string? CreditCard = null, string? Expiration = null, string? CCV = null) { + this.Id = Id; this.FirstName = FirstName; this.LastName = LastName; this.Email = Email; diff --git a/OpheliasOasis/Models/Reservation.cs b/OpheliasOasis/Models/Reservation.cs index ba9c94b..5f85949 100644 --- a/OpheliasOasis/Models/Reservation.cs +++ b/OpheliasOasis/Models/Reservation.cs @@ -1,19 +1,17 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Ophelias.Models; using Ophelias.Managers; +using System.Data.SQLite; namespace Ophelias.Models { internal class Reservation { internal int Id; - internal int RoomId; - internal int GuestId; - internal int TransactionId; + internal Room Room; + internal Guest Guest; + internal Transaction Transaction; internal bool IsNoShow; @@ -28,26 +26,57 @@ namespace Ophelias.Models internal DateTime? CheckOut; internal DateTime? DateChanged; - internal Reservation(int id, int gid, int tid, int room, ReservationType type, ReservationStatus status, - DateTime startdate, DateTime enddate) + internal Reservation(int Id, Guest Guest, Transaction Transaction, ReservationType Type, ReservationStatus Status, + DateTime CreationDate, DateTime StartDate, DateTime EndDate, bool IsNoShow = false, DateTime? CheckIn = null, DateTime? CheckOut = null, DateTime? DateChanged = null) { - Id = id; - RoomId = room; - GuestId = gid; - TransactionId = tid; + this.Id = Id; + this.Guest = Guest; + this.Transaction = Transaction; + this.IsNoShow = IsNoShow; + this.Type = Type; + this.Status = Status; + this.CreationDate = CreationDate; + this.StartDate = StartDate; + this.EndDate = EndDate; + this.CheckIn = CheckIn; + this.CheckOut = CheckOut; + this.DateChanged = DateChanged; + } + internal void ChangeReservationDates(DateTime StartDate, DateTime EndDate) + { + this.StartDate = StartDate; + this.EndDate = EndDate; + DateChanged = DateTime.Now.Date; + using (DatabaseManager Manager = new DatabaseManager()) + { + using (SQLiteCommand cmd = Manager.con.CreateCommand()) + { + string? query = QueryBuilder.UpdateReservation(Id: Id, Status: ReservationStatus.Changed, StartDate: this.StartDate, EndDate: this.EndDate, DateChanged: DateChanged); - IsNoShow = false; + if (query == null) + throw new Exception(); - Type = type; - Status = status; + cmd.CommandText = query; + cmd.ExecuteNonQuery(); + } + } + Transaction.UpdateTransactionFees(HotelManager.GetBaseRate(), TxFunctions.Changed, TxFunctions.GetPayByDate(Type, this.StartDate, this.EndDate)); + } + internal void CancelReservation() + { + using (DatabaseManager Manager = new DatabaseManager()) + { + using (SQLiteCommand cmd = Manager.con.CreateCommand()) + { + string? query = QueryBuilder.UpdateReservation(Id: Id, Status: ReservationStatus.Cancelled, DateChanged: DateTime.Now.Date); - CreationDate = DateTime.Now; - StartDate = startdate; - EndDate = enddate; + if (query == null) + throw new Exception(); - CheckIn = null; - CheckOut = null; - DateChanged = null; + cmd.CommandText = query; + cmd.ExecuteNonQuery(); + } + } } } internal enum ReservationStatus diff --git a/OpheliasOasis/Models/Room.cs b/OpheliasOasis/Models/Room.cs index d1bbe2e..0601331 100644 --- a/OpheliasOasis/Models/Room.cs +++ b/OpheliasOasis/Models/Room.cs @@ -4,7 +4,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -namespace OpheliasOasis.Models +namespace Ophelias.Models { internal class Room { diff --git a/OpheliasOasis/Models/Transaction.cs b/OpheliasOasis/Models/Transaction.cs index 8f267d9..6b2d957 100644 --- a/OpheliasOasis/Models/Transaction.cs +++ b/OpheliasOasis/Models/Transaction.cs @@ -5,13 +5,12 @@ using System.Text; using System.Threading.Tasks; using Ophelias.Models; using Ophelias.Managers; +using System.Data.SQLite; namespace Ophelias.Models { internal class Transaction { - private double PenaltyMultipler = 1.1; - internal int Id { get; set; } internal double Rate { get; set; } internal double Owed { get; set; } @@ -19,11 +18,12 @@ namespace Ophelias.Models internal double Multiplier { get; set; } internal double RefundAmount { get; set; } internal DateTime PayBy { get; set; } + internal DateTime? LastPaid { get; set; } = null; internal DateTime? PaidOn { get; set; } = null; - internal Transaction(int Id, double Rate, double Owed, double Penalty, - double Multiplier, double RefundAmount, - DateTime PayBy, DateTime? PaidOn = null) + internal Transaction(int Id, double Rate, double Owed, + double Multiplier, DateTime PayBy, DateTime? LastPaid = null, + DateTime? PaidOn = null, double RefundAmount = 0, double Penalty = 0) { this.Id = Id; this.Rate = Rate; @@ -32,79 +32,102 @@ namespace Ophelias.Models this.Multiplier = Multiplier; this.RefundAmount = RefundAmount; this.PayBy = PayBy; + this.LastPaid = LastPaid; this.PaidOn = PaidOn; } - private void Cancellation(ReservationType type) + internal void UpdateTransactionFees(double Rate, double Multiplier, DateTime PayBy) { - void SetRefund() + this.Rate = Rate; + this.Multiplier = Multiplier; + this.PayBy = PayBy; + using (DatabaseManager Manager = new DatabaseManager()) { - if (DateTime.Now.AddDays(+3).Day <= PayBy.Day) + using (SQLiteCommand cmd = Manager.con.CreateCommand()) { - RefundAmount = Paid; - Paid = 0; - Owed = 0; - PaidOff = false; + string? query = QueryBuilder.UpdateTransaction(Id: Id, Rate: this.Rate, Multiplier: this.Multiplier, PayBy: this.PayBy); + + if (query == null) + throw new Exception(); + + cmd.CommandText = query; + cmd.ExecuteNonQuery(); } } - - switch (type) + } + internal void Pay(double Amount) + { + if (Amount <= 0) + return; + LastPaid = DateTime.Now; + Owed -= Amount; + if (Owed < 0) + RefundAmount = Math.Abs(Owed); + else if (Owed == 0) + PaidOn = DateTime.Now; + using (DatabaseManager Manager = new DatabaseManager()) { - case ReservationType.Conventional: SetRefund(); return; - case ReservationType.Prepaid: return; - case ReservationType.Incentive: SetRefund(); return; - case ReservationType.SixtyDayAdvance: return; - default: throw new NotImplementedException(); + using (SQLiteCommand cmd = Manager.con.CreateCommand()) + { + string? query = QueryBuilder.UpdateTransaction(Id: Id, Owed: Owed, Refund: RefundAmount, LastPaid: LastPaid, PaidOn: PaidOn); + + if (query == null) + throw new Exception(); + + cmd.CommandText = query; + cmd.ExecuteNonQuery(); + } } } - internal void Penalize(Reservation r) + internal void Refund() { - switch (r.Status) + RefundAmount = 0; + using (DatabaseManager Manager = new DatabaseManager()) { - case ReservationStatus.Active: IsOverdue(); return; - case ReservationStatus.Ended: IsOverdue(); return; - case ReservationStatus.Cancelled: CancellationHandler(r.Type); return; - default: throw new NotImplementedException(); + using (SQLiteCommand cmd = Manager.con.CreateCommand()) + { + string? query = QueryBuilder.UpdateTransaction(Id: Id, Refund: RefundAmount); + + if (query == null) + throw new Exception(); + + cmd.CommandText = query; + cmd.ExecuteNonQuery(); + } } } - internal void Penalize(Reservation r, double rate) - { - throw new NotImplementedException(); - } - - internal void Pay(double amount) - { - - } } - internal static class TransactionInfo + internal static class TxFunctions { internal static double ConventionalFee = 1.0; internal static double PrepaidFee = 0.75; - internal static double IncentiveFee = IncentiveRate(); internal static double SixtyDayFee = 0.85; - - private static double IncentiveRate() + internal static double Changed = 1.1; + internal static double IncentiveFee(DateTime Start, DateTime End) { int thirtyDayOcc; - thirtyDayOcc = HotelManager.GetThirtyDayOccupancy(DateTime.Now); + thirtyDayOcc = HotelManager.AvgOccupancySpan(Start, End); if ((double)(thirtyDayOcc / 45.0) <= 0.6) return 0.80; return 1.0; } - - internal static DateTime GetPayByDate(Reservation r) + internal static DateTime GetPayByDate(ReservationType Type, DateTime StartDate, DateTime EndDate) { - switch (r.Type) + switch (Type) { - case ReservationType.Conventional: return r.EndDate; - case ReservationType.Prepaid: return r.StartDate; - case ReservationType.Incentive: return r.EndDate; - case ReservationType.SixtyDayAdvance: return r.StartDate.AddDays(-30); + case ReservationType.Conventional: return EndDate; + case ReservationType.Prepaid: return StartDate; + case ReservationType.Incentive: return EndDate; + case ReservationType.SixtyDayAdvance: return StartDate.AddDays(-30); default: throw new NotImplementedException(); } } + internal static double CalculateOwed(double Rate, int Days) + { + return Rate * (double)Days; + } + } internal class TransactionList diff --git a/OpheliasOasis/Program.cs b/OpheliasOasis/Program.cs index 5ff948f..2fa774e 100644 --- a/OpheliasOasis/Program.cs +++ b/OpheliasOasis/Program.cs @@ -9,72 +9,14 @@ class Program { Reservation? activeReservation = null; Guest? activeGuest = null; - - void help() - { - Console.WriteLine( - "Reservation Commands:\n" + - "\treservation create\n" + - "\treservation update\n" + - "\treservation cancel\n" + - "Account Commands:\n" + - "\taccount create\n" + - "\taccount update\n" + - "Enter Q to quit.\n" - ); - return; - } - - - - void CreateNewReservation() - { - Reservation newReservation; - } - - void CreateNewGuestPrompt() - { - (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: "); + 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 = ""; @@ -84,7 +26,38 @@ class Program 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 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; + } + void GuestLogin() + { + Console.Write("\nEnter your email address: "); string email = ""; while (!Validation.ValidateEmail(email)) { @@ -92,16 +65,234 @@ class Program 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}."); + Console.WriteLine($"\nYou have logged into {activeGuest.FirstName} {activeGuest.LastName} ({email})."); + } + 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 = HotelManager.CreateGuest(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 NewDetails = new List(); + 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}"); + HotelManager.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 "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); + } + void CreateNewReservation() + { + if (activeGuest == null) + Console.WriteLine("No guest is currently logged in, please login."); + if (activeReservation != null) + Console.WriteLine(""); + + string input = ""; + ReservationType SelectReservation() + { + 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() + { + 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); + } + + ReservationType Type; + DateTime StartDate; + DateTime EndDate; + + Type = SelectReservation(); + (StartDate, EndDate) = SelectDate(); + if (Type != ReservationType.SixtyDayAdvance && + (activeGuest.CreditCard == null || activeGuest.Expiration == null || activeGuest.CCV == null)) + GetCreditCardInformation(); + + Console.WriteLine($"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. If they are not enter...\n" + + $"1. Change your reservation type\n" + + $"2. Change your reservation dates\n" + + $": "); + input = Console.ReadLine(); + if (input != "YES") + { + bool completed = false; + do + { + Console.Write("Would you like to edit any information, enter Q to exit and complete your reservation?\n" + + "1. Reservation type\n" + + "2. Reservation dates\n" + + "Enter 1 or 2: "); + switch (Console.ReadLine()) + { + case "Q": completed = true; break; + case "q": completed = true; break; + case "1": SelectReservation(); break; + case "2": SelectDate(); break; + default: break; + } + } while (!completed); + } + HotelManager.CreateReservation(activeGuest, Type, DateTime.Now.Date, StartDate, EndDate); + } + (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); } Console.Write( - "Welcome to the Ophelias Oasis Hotel Registration System!\n" + + "\nWelcome to the Ophelias Oasis Hotel Registration System!\n" + "Type help to get a full list of commands or enter a command.\n" + "Command: " ); @@ -112,15 +303,16 @@ class Program switch(input) { case "help": help(); break; - case "reservation create": break; + case "reservation create": CreateNewReservation(); break; case "reservation update": break; case "reservation cancel": break; case "account create": CreateNewGuestPrompt(); break; - case "account update": 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("Command: "); + Console.Write("\nCommand: "); } } private void AdminMode()