304 lines
14 KiB
C#
304 lines
14 KiB
C#
using Ophelias.Managers;
|
|
using System.Data.SQLite;
|
|
|
|
namespace Ophelias.Models
|
|
{
|
|
internal class Reservation
|
|
{
|
|
/*
|
|
* The reservation class is comprised of many pieces of information. For details on the
|
|
* Guest and Transaction components, see Guest and Transaction classes.
|
|
*
|
|
* Reservations are comprised of the following:
|
|
*
|
|
* ID
|
|
* Identifies the reservation
|
|
*
|
|
* RoomNum
|
|
* Indicates what room the guest is staying/ stayed in
|
|
*
|
|
* Guest
|
|
* See Guest.cs model class
|
|
*
|
|
* Transaction
|
|
* See Transaction.cs model class
|
|
*
|
|
* IsNoShow
|
|
* Boolean to indicate if someone is a no-show/ does not show up to their
|
|
* scheduled reservation
|
|
*
|
|
* Type
|
|
* The type of reservation made (Conventional, Prepaid, Incentive, 60-day/ Advance)
|
|
*
|
|
* Status
|
|
* Indicates if the reservation is active, changed, cancelled, or ended
|
|
*
|
|
* CreationDate
|
|
* The date the reservation was created
|
|
*
|
|
* StartDate
|
|
* The date the reservation is scheduled to being
|
|
*
|
|
* EndDate
|
|
* The date the reservation is scheduled to end
|
|
*
|
|
* CheckIn
|
|
* Reflects when the guest checked in, currently mirrors StartDate when set
|
|
*
|
|
* CheckOut
|
|
* Reflects when the guest checked out, currently mirrors EndDate when set
|
|
*
|
|
* DateChanged
|
|
* The date the reservation was updated/ changed
|
|
*/
|
|
internal int Id;
|
|
internal int? RoomNum;
|
|
internal Guest Guest;
|
|
internal Transaction Transaction;
|
|
|
|
internal bool IsNoShow;
|
|
|
|
internal ReservationType Type;
|
|
internal ReservationStatus Status;
|
|
|
|
internal DateTime CreationDate;
|
|
internal DateTime StartDate;
|
|
internal DateTime EndDate;
|
|
|
|
internal DateTime? CheckIn;
|
|
internal DateTime? CheckOut;
|
|
internal DateTime? DateChanged;
|
|
|
|
internal Reservation(Guest Guest, ReservationType Type,
|
|
DateTime CreationDate, DateTime StartDate, DateTime EndDate, ReservationStatus Status = ReservationStatus.Active,
|
|
bool IsNoShow = false, DateTime? CheckIn = null, DateTime? CheckOut = null, DateTime? DateChanged = null, int? RoomNum = null)
|
|
{
|
|
/*
|
|
* Creates a new reservation assuming it never existed in the first place.
|
|
*
|
|
* Upon creating a reservation, this function will set the appropriate fees
|
|
* based on the type of reservation. See TxFunctions in the transaction class
|
|
* for the specific fee multiplier values. The base rate is then retrieved for
|
|
* the current date if a new one was set for that date, otherwise the base rate
|
|
* used is whatever the default last was. We do not tether the rate to an ID
|
|
* since the rate only changes when the reservation is tweaked. This information
|
|
* is then passed off to create a new Transaction. See the Transaction class for
|
|
* more information.
|
|
*
|
|
* Once a new transaction has been created, a database connection is opened to create
|
|
* a new reservation and the ID generated is returned back. This value is then set
|
|
* to the reservation and a new instance is returned.
|
|
*/
|
|
int Id; double Multiplier;
|
|
switch (Type) // Determines the appropriate fee multiplier to set
|
|
{
|
|
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();
|
|
}
|
|
double? BaseRate = Hotel.GetBaseRate(); // Checks to see if there is a new base rate and uses the rate returned, old default or new default
|
|
if (BaseRate == null) // Exists for the unlikely situation a reservation is made on a null rate
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
Transaction Transaction = new( // Creates a new transaction, see the Transaction class for more details on TxFunctions or trnsaction itself
|
|
Rate: (double)BaseRate,
|
|
Owed: TxFunctions.CalculateOwed((double)BaseRate, (int)(EndDate.Date - StartDate.Date).TotalDays, Multiplier),
|
|
Multiplier: Multiplier,
|
|
PayBy: TxFunctions.GetPayByDate(Type, StartDate, EndDate)
|
|
);
|
|
using (Database Manager = new()) // Creates a new database connection
|
|
{
|
|
using (SQLiteCommand cmd = Manager.con.CreateCommand()) // Creates a new command that will be executed in the database
|
|
{
|
|
if (RoomNum != null)
|
|
{
|
|
this.RoomNum = RoomNum;
|
|
}
|
|
|
|
/*
|
|
* The folowing is a query with parameters that are set based off certain conditions,
|
|
* such as if the value exists.
|
|
*/
|
|
cmd.CommandText =
|
|
"INSERT INTO reservations (RoomNum, GuestID, TransactionID, IsNoShow, Type, Status, CreationDate, StartDate, EndDate, CheckIn, CheckOut, DateChanged) " +
|
|
"VALUES (@RoomNum, @GuestID, @TransactionID, @IsNoShow, @Type, @Status, @CreationDate, @StartDate, @EndDate, @CheckIn, @CheckOut, @DateChanged);";
|
|
cmd.Parameters.AddWithValue("@RoomNum", RoomNum);
|
|
cmd.Parameters.AddWithValue("@GuestID", Guest.Id);
|
|
cmd.Parameters.AddWithValue("@TransactionID", Transaction.Id);
|
|
cmd.Parameters.AddWithValue("@IsNoShow", Convert.ToInt32(IsNoShow));
|
|
cmd.Parameters.AddWithValue("@Type", (int)Type);
|
|
cmd.Parameters.AddWithValue("@Status", (int)Status);
|
|
cmd.Parameters.AddWithValue("@CreationDate", CreationDate.ToString("yyyy-MM-dd"));
|
|
cmd.Parameters.AddWithValue("@StartDate", StartDate.ToString("yyyy-MM-dd"));
|
|
cmd.Parameters.AddWithValue("@EndDate", EndDate.ToString("yyyy-MM-dd"));
|
|
if (CheckIn.HasValue)
|
|
{
|
|
cmd.Parameters.AddWithValue("@CheckIn", CheckIn.Value.ToString("yyyy-MM-dd"));
|
|
}
|
|
else
|
|
{
|
|
cmd.Parameters.AddWithValue("@CheckIn", CheckIn);
|
|
}
|
|
|
|
if (CheckOut.HasValue)
|
|
{
|
|
cmd.Parameters.AddWithValue("@CheckOut", CheckOut.Value.ToString("yyyy-MM-dd"));
|
|
}
|
|
else
|
|
{
|
|
cmd.Parameters.AddWithValue("@CheckOut", CheckOut);
|
|
}
|
|
|
|
if (DateChanged.HasValue)
|
|
{
|
|
cmd.Parameters.AddWithValue("@DateChanged", DateChanged.Value.ToString("yyyy-MM-dd"));
|
|
}
|
|
else
|
|
{
|
|
cmd.Parameters.AddWithValue("@DateChanged", DateChanged);
|
|
}
|
|
|
|
cmd.ExecuteNonQuery();
|
|
}
|
|
Id = (int)Manager.con.LastInsertRowId; // Sets the ID returned by the query
|
|
}
|
|
this.Id = Id;
|
|
this.RoomNum = RoomNum;
|
|
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 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, int? RoomNum = null)
|
|
{
|
|
/*
|
|
* This creates and returns a reservation assuming it already existed
|
|
* as an ID is required if the reservation exists in the system.
|
|
*/
|
|
this.Id = Id;
|
|
this.RoomNum = RoomNum;
|
|
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)
|
|
{
|
|
/*
|
|
* Change Reservation Dates allows for the manipulation of start and end dates.
|
|
* These changes saved to the reservation and reflected in the database.
|
|
* It also makes a call to update the transaction fees. See Transaction class for
|
|
* details on this. A new rate and multiplier are set also since reservation changes
|
|
* come at the cost of paying based on the most recent base rate and 110% multipler.
|
|
*/
|
|
this.StartDate = StartDate;
|
|
this.EndDate = EndDate;
|
|
DateChanged = DateTime.Now.Date;
|
|
using (Database Manager = new()) // Creates a new database connection
|
|
{
|
|
using (SQLiteCommand cmd = Manager.con.CreateCommand()) // Creates a new command that will be executed in the database
|
|
{
|
|
string? query = QueryBuilder.UpdateReservation(Id: Id, Status: ReservationStatus.Changed, StartDate: this.StartDate, EndDate: this.EndDate, DateChanged: DateChanged); // Builds a new query string with parameters
|
|
|
|
if (query == null)
|
|
{
|
|
throw new Exception();
|
|
}
|
|
|
|
cmd.CommandText = query;
|
|
cmd.Parameters.AddWithValue("@ID", Id);
|
|
cmd.Parameters.AddWithValue("@Status", Status);
|
|
cmd.Parameters.AddWithValue("@StartDate", StartDate.ToString("yyyy-MM-dd"));
|
|
cmd.Parameters.AddWithValue("@EndDate", EndDate.ToString("yyyy-MM-dd"));
|
|
cmd.Parameters.AddWithValue("@DateChanged", DateChanged.Value.ToString("yyyy-MM-dd"));
|
|
cmd.ExecuteNonQuery();
|
|
}
|
|
}
|
|
double? BaseRate = Hotel.GetBaseRate(); // Checks for the most recent rate to replace the old rate
|
|
if (BaseRate == null)
|
|
{
|
|
throw new ArgumentNullException(nameof(BaseRate));
|
|
}
|
|
|
|
Transaction.UpdateTransactionFees((double)BaseRate, TxFunctions.Changed, TxFunctions.GetPayByDate(Type, this.StartDate, this.EndDate)); // Creates a new transaction
|
|
}
|
|
internal void CancelReservation()
|
|
{
|
|
/*
|
|
* Cancel Reservation will cancel the existing reservation and issue penalties
|
|
* if they apply. Specifically if the reservation type is conventional, incentive,
|
|
* or the reservation is past due and the right criteria are met, the transaction
|
|
* class calls the pay function and the accounts are charged. See Transaction.Pay()
|
|
* for more details. The reservation is also set to cancelled in the database.
|
|
*/
|
|
DateTime _DateChanged = DateTime.Now.Date;
|
|
using (Database Manager = new()) // Creates a new database connection
|
|
{
|
|
using (SQLiteCommand cmd = Manager.con.CreateCommand()) // Creates a new command that will be executed in the database
|
|
{
|
|
string? query = QueryBuilder.UpdateReservation(Id: Id, Status: ReservationStatus.Cancelled, DateChanged: _DateChanged); // Builds a new query string with parameters
|
|
|
|
if (query == null)
|
|
{
|
|
throw new Exception();
|
|
}
|
|
|
|
Status = ReservationStatus.Cancelled;
|
|
DateChanged = _DateChanged;
|
|
|
|
cmd.CommandText = query;
|
|
cmd.Parameters.AddWithValue("@ID", Id);
|
|
cmd.Parameters.AddWithValue("@Status", Status);
|
|
cmd.Parameters.AddWithValue("@DateChanged", DateChanged.Value.ToString("yyyy-MM-dd"));
|
|
cmd.ExecuteNonQuery();
|
|
}
|
|
}
|
|
if (Type == ReservationType.Conventional && _DateChanged.Date >= StartDate.AddDays(-3).Date) // Charge conventional reservations cancelled three or less days of stay
|
|
{
|
|
Transaction.Pay(Transaction.Owed, Guest.CreditCard);
|
|
}
|
|
else if (Type == ReservationType.Incentive && _DateChanged.Date >= StartDate.AddDays(-3).Date) // Charge incentive based on the same policy as conventional
|
|
{
|
|
Transaction.Pay(Transaction.Owed, Guest.CreditCard);
|
|
}
|
|
else if (_DateChanged.Date > StartDate.Date) // Charge based on no-show
|
|
{
|
|
Transaction.Pay(Transaction.Owed, Guest.CreditCard);
|
|
}
|
|
}
|
|
}
|
|
internal enum ReservationStatus // Represets numerical values as words
|
|
{
|
|
Active,
|
|
Changed,
|
|
Cancelled,
|
|
Ended,
|
|
}
|
|
internal enum ReservationType // Represents numerical values as words
|
|
{
|
|
Conventional,
|
|
Prepaid,
|
|
SixtyDayAdvance,
|
|
Incentive,
|
|
}
|
|
}
|