The calculations used in the reports were calulating based off the owed column which mathematically did not make sense since we are looking for the daily.
1148 lines
59 KiB
C#
1148 lines
59 KiB
C#
using Ophelias.Models;
|
|
using System.Data.SQLite;
|
|
|
|
namespace Ophelias.Managers
|
|
{
|
|
internal static class Hotel
|
|
{
|
|
/*
|
|
* This class is a large collection of SQL queries that did not belong
|
|
* on a specific model. As a result they are viewed as functions of the "Hotel".
|
|
* For details on what each does, see their docstrings. All queries here are
|
|
* written using parameters to avoid SQL injection.
|
|
*/
|
|
internal static (List<(DateTime, int, string, string)>, List<int>) GetDailyOccupancy()
|
|
{
|
|
/*
|
|
* This function gets the daily occupancies by joining the reservation table
|
|
* with the guests and rooms table. It looks for where the current date is between
|
|
* any active/ changed reservation's, that has been checked in, start and end date.
|
|
* The query is then put in ascending order, or, organized by room number.
|
|
*/
|
|
List<int> previousOccupancies = new();
|
|
List<(DateTime, int, string, string)> currentOccupancies = new();
|
|
using (Database Manager = new()) // Open a new database connection
|
|
{
|
|
using SQLiteTransaction Transaction = Manager.con.BeginTransaction(); // Being a new SQL transaction
|
|
using (SQLiteCommand cmd = Manager.con.CreateCommand()) // Create a new command to execute
|
|
{
|
|
cmd.CommandText = "SELECT RoomNum, Lname, Fname, EndDate FROM reservations " +
|
|
"INNER JOIN guests ON reservations.GuestID = guests.ID " +
|
|
"INNER JOIN rooms ON reservations.RoomNum = rooms.ID " +
|
|
"WHERE (DATE(@Date) BETWEEN StartDate AND EndDate) AND Status IN (@Status1,@Status2) AND CheckIn IS NOT NULL " +
|
|
"ORDER BY RoomNum ASC;";
|
|
cmd.Parameters.AddWithValue("@Date", DateTime.Now.Date.ToString("yyyy-MM-dd"));
|
|
cmd.Parameters.AddWithValue("@Status1", (int)ReservationStatus.Active);
|
|
cmd.Parameters.AddWithValue("@Status2", (int)ReservationStatus.Changed);
|
|
using SQLiteDataReader reader = cmd.ExecuteReader(); // Create a new reader to read the SQL data
|
|
while (reader.Read())
|
|
{
|
|
currentOccupancies.Add((reader.GetDateTime(3), reader.GetInt32(0), reader.GetString(1), reader.GetString(2)));
|
|
}
|
|
}
|
|
using (SQLiteCommand cmd = Manager.con.CreateCommand()) // Create a new command to execute
|
|
{
|
|
cmd.CommandText = "SELECT RoomNum FROM reservations " +
|
|
"INNER JOIN guests ON reservations.GuestID = guests.ID " +
|
|
"INNER JOIN rooms ON reservations.RoomNum = rooms.ID " +
|
|
"WHERE DATE (DATE(@Date) BETWEEN StartDate AND EndDate) AND Status IN (@Status1);";
|
|
cmd.Parameters.AddWithValue("@Date", DateTime.Now.AddDays(-1).Date.ToString("yyyy-MM-dd"));
|
|
cmd.Parameters.AddWithValue("@Status1", (int)ReservationStatus.Ended);
|
|
using SQLiteDataReader reader = cmd.ExecuteReader(); // Create a new reader to read the SQL data
|
|
while (reader.Read())
|
|
{
|
|
foreach (int item in reader.GetValues())
|
|
{
|
|
previousOccupancies.Add(item);
|
|
}
|
|
}
|
|
}
|
|
Transaction.Commit(); // Commit the transaction changes if any made
|
|
}
|
|
return (currentOccupancies, previousOccupancies);
|
|
}
|
|
internal static List<Reservation> GetDailyArrivals()
|
|
{
|
|
/*
|
|
* This function queries for daily arrivals. A daily arrival is considered to be someone
|
|
* that arrives on the current date and has an active or changed reservation status.
|
|
* Using these conditions, the transaction and guest table are joined and then the
|
|
* data is ordered by the guests last name in ascending order.
|
|
*/
|
|
List<Reservation> reservations = new();
|
|
using (Database Manager = new()) // Open a new database connection
|
|
{
|
|
using SQLiteCommand cmd = Manager.con.CreateCommand(); // Create a new command to execute
|
|
cmd.CommandText = "SELECT * FROM reservations " +
|
|
"INNER JOIN transactions ON reservations.TransactionID = transactions.ID " +
|
|
"INNER JOIN guests ON reservations.GuestID = guests.ID " +
|
|
"WHERE DATE (@Date) = StartDate AND Status IN (@Status1,@Status2)" +
|
|
"ORDER BY Lname ASC;";
|
|
cmd.Parameters.AddWithValue("@Date", DateTime.Now.Date.ToString("yyyy-MM-dd"));
|
|
cmd.Parameters.AddWithValue("@Status1", (int)ReservationStatus.Active);
|
|
cmd.Parameters.AddWithValue("@Status2", (int)ReservationStatus.Changed);
|
|
using SQLiteDataReader reader = cmd.ExecuteReader(); // Create a new reader to read the SQL data
|
|
while (reader.Read())
|
|
{
|
|
/*
|
|
* Since we cannot get by string keys, each column is represented by a numerical value
|
|
* like an array. The column is as follows:
|
|
*
|
|
* 0. ID (reservations.ID)
|
|
* 1. RoomNum
|
|
* 2. GuestID
|
|
* 3. TransactionID
|
|
* 4. IsNoShow
|
|
* 5. Type
|
|
* 6. Status
|
|
* 7. CreationDate
|
|
* 8. StartDate
|
|
* 9. EndDate
|
|
* 10. CheckIn
|
|
* 11. CheckOut
|
|
* 12. DateChanged
|
|
* 13. ID (rooms.ID)
|
|
* 14. Rate
|
|
* 15. Owed
|
|
* 16. Penalty
|
|
* 17. Multiplier
|
|
* 18. RefundAmount
|
|
* 19. AmountPaid
|
|
* 20. PayBy
|
|
* 21. LastPaid
|
|
* 22. PaidOn
|
|
* 23. ID (guests.ID)
|
|
* 24. Fname
|
|
* 25. Lname
|
|
* 26. Email
|
|
* 27. CreditCard
|
|
* 28. Expiration
|
|
* 29. CCV
|
|
*
|
|
*/
|
|
Reservation? r;
|
|
Transaction? t;
|
|
Guest g;
|
|
int? RoomNumber = null;
|
|
DateTime? CheckIn = null, CheckOut = null, DateChanged = null, LastPaid = null, PaidOn = null;
|
|
|
|
if (reader.HasRows && !reader.IsDBNull(0))
|
|
{
|
|
if (reader[21].GetType() != typeof(DBNull))
|
|
{
|
|
LastPaid = reader.GetDateTime(21);
|
|
}
|
|
|
|
if (reader[22].GetType() != typeof(DBNull))
|
|
{
|
|
PaidOn = reader.GetDateTime(22);
|
|
}
|
|
|
|
t = new(reader.GetInt32(13), reader.GetDouble(14), reader.GetDouble(15), reader.GetDouble(17), reader.GetDateTime(20), // Creates a new transaction implicitly
|
|
LastPaid: LastPaid, PaidOn: PaidOn, RefundAmount: reader.GetDouble(18), Penalty: reader.GetDouble(16), AmountPaid: reader.GetDouble(19));
|
|
|
|
g = new(reader.GetInt32(23), reader.GetString(24), reader.GetString(25), reader.GetString(26), reader.GetString(27), reader.GetString(28), reader.GetString(29)); // Creates a new guest implicitly
|
|
|
|
if (reader[1].GetType() != typeof(DBNull))
|
|
{
|
|
RoomNumber = reader.GetInt32(1);
|
|
}
|
|
|
|
if (reader[10].GetType() != typeof(DBNull))
|
|
{
|
|
CheckIn = reader.GetDateTime(10);
|
|
}
|
|
|
|
if (reader[11].GetType() != typeof(DBNull))
|
|
{
|
|
CheckOut = reader.GetDateTime(11);
|
|
}
|
|
|
|
if (reader[12].GetType() != typeof(DBNull))
|
|
{
|
|
DateChanged = reader.GetDateTime(12);
|
|
}
|
|
|
|
r = new(reader.GetInt32(0), g, t, (ReservationType)reader.GetInt32(5), (ReservationStatus)reader.GetInt32(6), // Creates a new reservation implicitly
|
|
reader.GetDateTime(7), reader.GetDateTime(8), reader.GetDateTime(9), RoomNum: RoomNumber, IsNoShow: reader.GetBoolean(4),
|
|
CheckIn: CheckIn, CheckOut: CheckOut, DateChanged: DateChanged);
|
|
reservations.Add(r);
|
|
}
|
|
}
|
|
}
|
|
return reservations;
|
|
}
|
|
internal static (double, double, List<(DateTime, double)>) GetIncentiveTransactions()
|
|
{
|
|
/*
|
|
* Creates a list of incentive transactions based on a query that gets reservations, and their associated transactions,
|
|
* if they match the Incentive type and are active and changed. The matching dates and rates and amount owed are caluclated
|
|
* to produce a new column losses. The losses are then added to a list, averaged, and totalled. These are returned.
|
|
*/
|
|
double losses;
|
|
double totalLosses = 0;
|
|
int days = 30;
|
|
DateTime dt = DateTime.Now;
|
|
List<(DateTime, double)> dailyLosses = new();
|
|
using (Database Manager = new()) // Create a new database connection
|
|
{
|
|
for (int i = 0; i < days; i++)
|
|
{
|
|
using (SQLiteCommand cmd = Manager.con.CreateCommand()) // Create a new command to execute
|
|
{
|
|
cmd.CommandText = "SELECT sum(transactions.Rate - (transactions.Rate * transactions.Multiplier)) AS Loss " +
|
|
"FROM reservations " +
|
|
"INNER JOIN transactions ON reservations.TransactionID = transactions.ID " +
|
|
"WHERE (DATE(@Date) BETWEEN StartDate AND EndDate) AND STATUS IN (@Status1,@Status2) AND Type = @Type";
|
|
cmd.Parameters.AddWithValue("@Date", dt.AddDays(i).Date.ToString("yyyy-MM-dd"));
|
|
cmd.Parameters.AddWithValue("@Status1", (int)ReservationStatus.Active);
|
|
cmd.Parameters.AddWithValue("@Status2", (int)ReservationStatus.Changed);
|
|
cmd.Parameters.AddWithValue("@Type", (int)ReservationType.Incentive);
|
|
using SQLiteDataReader reader = cmd.ExecuteReader(); // Create a new reader to read the SQL data
|
|
reader.Read();
|
|
if (reader.HasRows && !reader.IsDBNull(0))
|
|
{
|
|
totalLosses += reader.GetDouble(0);
|
|
losses = reader.GetDouble(0);
|
|
}
|
|
else // No losses found
|
|
{
|
|
losses = 0;
|
|
}
|
|
}
|
|
dailyLosses.Add((dt.AddDays(i), losses));
|
|
}
|
|
}
|
|
return (totalLosses, totalLosses / 30, dailyLosses);
|
|
}
|
|
internal static (List<(DateTime, double)>, double, double) GetExpectedIncomeCount()
|
|
{
|
|
/*
|
|
* This query gets the the expected income for the next thirty days. The query looks
|
|
* for and sums transactions that cover the specified date range and are active or
|
|
* changed in status. The expected income is averaged as well and returned as daily
|
|
* values.
|
|
*/
|
|
double totalIncome = 0;
|
|
double income;
|
|
int days = 30;
|
|
DateTime dt = DateTime.Now;
|
|
List<(DateTime, double)> dailyIncomes = new();
|
|
using (Database Manager = new()) // Create a new database connection
|
|
{
|
|
for (int i = 0; i < days; i++)
|
|
{
|
|
using (SQLiteCommand cmd = Manager.con.CreateCommand()) // Create a new command to execute
|
|
{
|
|
cmd.CommandText = "SELECT sum(transactions.Rate * Multiplier) FROM reservations " +
|
|
"INNER JOIN transactions ON reservations.TransactionID = transactions.ID " +
|
|
"WHERE (DATE(@Date) BETWEEN StartDate AND EndDate) AND Status IN (@Status1,@Status2);";
|
|
cmd.Parameters.AddWithValue("@Date", dt.AddDays(i).Date.ToString("yyyy-MM-dd"));
|
|
cmd.Parameters.AddWithValue("@Status1", (int)ReservationStatus.Active);
|
|
cmd.Parameters.AddWithValue("@Status2", (int)ReservationStatus.Changed);
|
|
|
|
using SQLiteDataReader reader = cmd.ExecuteReader(); // Create a new reader to read the SQL data
|
|
reader.Read();
|
|
if (reader.HasRows && !reader.IsDBNull(0))
|
|
{
|
|
totalIncome += reader.GetDouble(0);
|
|
income = reader.GetDouble(0);
|
|
}
|
|
else
|
|
{
|
|
income = 0;
|
|
}
|
|
}
|
|
dailyIncomes.Add((dt.AddDays(i), income));
|
|
}
|
|
}
|
|
return (dailyIncomes, totalIncome, totalIncome / 30);
|
|
}
|
|
internal static (double, List<(DateTime, int, int, int, int, int)>) GetExpectedOccupancyCount()
|
|
{
|
|
/*
|
|
* This function gets the expected occupancy for the next thirty days. The query looks for
|
|
* active or changed reservations based on the current date between matching reservations
|
|
* start and end dates. It also runs the query for all and each reservation respectively.
|
|
*/
|
|
double thirtyDayOcc = 0;
|
|
int days = 30;
|
|
DateTime dt = DateTime.Now;
|
|
List<(DateTime, int, int, int, int, int)> occData = new();
|
|
using (Database Manager = new()) // Create a new database connection
|
|
{
|
|
for (int i = 0; i < days; i++)
|
|
{
|
|
int rooms, conventional, prepaid, sixty, incentive;
|
|
using (SQLiteTransaction Transaction = Manager.con.BeginTransaction()) // Create a new transaction
|
|
{
|
|
using (SQLiteCommand cmd = Manager.con.CreateCommand()) // Create a new command to execute
|
|
{
|
|
cmd.CommandText = "SELECT COUNT(*) " +
|
|
"FROM reservations " +
|
|
"WHERE (DATE(@Date) BETWEEN StartDate AND EndDate) AND Status in (@Status1,@Status2);";
|
|
cmd.Parameters.AddWithValue("@Date", dt.AddDays(i).Date.ToString("yyyy-MM-dd"));
|
|
cmd.Parameters.AddWithValue("@Status1", (int)ReservationStatus.Active);
|
|
cmd.Parameters.AddWithValue("@Status2", (int)ReservationStatus.Changed);
|
|
|
|
using SQLiteDataReader reader = cmd.ExecuteReader(); // Create a new reader to read the SQL data
|
|
reader.Read();
|
|
if (reader.HasRows && !reader.IsDBNull(0))
|
|
{
|
|
thirtyDayOcc += reader.GetInt32(0);
|
|
rooms = reader.GetInt32(0);
|
|
}
|
|
else
|
|
{
|
|
rooms = 0;
|
|
}
|
|
}
|
|
using (SQLiteCommand cmd = Manager.con.CreateCommand()) // Create a new command to execute
|
|
{
|
|
/*
|
|
* Get total conventional count
|
|
*/
|
|
cmd.CommandText = "SELECT COUNT(*) " +
|
|
"FROM reservations " +
|
|
"WHERE (DATE(@Date) BETWEEN StartDate AND EndDate) AND Status in (@Status1,@Status2) AND Type = @Type;";
|
|
cmd.Parameters.AddWithValue("@Date", dt.AddDays(i).Date.ToString("yyyy-MM-dd"));
|
|
cmd.Parameters.AddWithValue("@Status1", (int)ReservationStatus.Active);
|
|
cmd.Parameters.AddWithValue("@Status2", (int)ReservationStatus.Changed);
|
|
cmd.Parameters.AddWithValue("@Type", (int)ReservationType.Conventional);
|
|
|
|
using SQLiteDataReader reader = cmd.ExecuteReader(); // Create a new reader to read the SQL data
|
|
reader.Read();
|
|
if (reader.HasRows && !reader.IsDBNull(0))
|
|
{
|
|
conventional = reader.GetInt32(0);
|
|
}
|
|
else
|
|
{
|
|
conventional = 0;
|
|
}
|
|
}
|
|
using (SQLiteCommand cmd = Manager.con.CreateCommand())
|
|
{
|
|
/*
|
|
* Get total prepaid count
|
|
*/
|
|
cmd.CommandText = "SELECT COUNT(*) " +
|
|
"FROM reservations " +
|
|
"WHERE (DATE(@Date) BETWEEN StartDate AND EndDate) AND Status in (@Status1,@Status2) AND Type = @Type;";
|
|
cmd.Parameters.AddWithValue("@Date", dt.AddDays(i).Date.ToString("yyyy-MM-dd"));
|
|
cmd.Parameters.AddWithValue("@Status1", (int)ReservationStatus.Active);
|
|
cmd.Parameters.AddWithValue("@Status2", (int)ReservationStatus.Changed);
|
|
cmd.Parameters.AddWithValue("@Type", (int)ReservationType.Prepaid);
|
|
|
|
using SQLiteDataReader reader = cmd.ExecuteReader();
|
|
reader.Read();
|
|
if (reader.HasRows && !reader.IsDBNull(0))
|
|
{
|
|
prepaid = reader.GetInt32(0);
|
|
}
|
|
else
|
|
{
|
|
prepaid = 0;
|
|
}
|
|
}
|
|
using (SQLiteCommand cmd = Manager.con.CreateCommand())
|
|
{
|
|
/*
|
|
* Get total 60-day-in-advance count
|
|
*/
|
|
cmd.CommandText = "SELECT COUNT(*) " +
|
|
"FROM reservations " +
|
|
"WHERE (DATE(@Date) BETWEEN StartDate AND EndDate) AND Status in (@Status1,@Status2) AND Type = @Type;";
|
|
cmd.Parameters.AddWithValue("@Date", dt.AddDays(i).Date.ToString("yyyy-MM-dd"));
|
|
cmd.Parameters.AddWithValue("@Status1", (int)ReservationStatus.Active);
|
|
cmd.Parameters.AddWithValue("@Status2", (int)ReservationStatus.Changed);
|
|
cmd.Parameters.AddWithValue("@Type", (int)ReservationType.SixtyDayAdvance);
|
|
|
|
using SQLiteDataReader reader = cmd.ExecuteReader();
|
|
reader.Read();
|
|
if (reader.HasRows && !reader.IsDBNull(0))
|
|
{
|
|
sixty = reader.GetInt32(0);
|
|
}
|
|
else
|
|
{
|
|
sixty = 0;
|
|
}
|
|
}
|
|
using (SQLiteCommand cmd = Manager.con.CreateCommand())
|
|
{
|
|
/*
|
|
* Get total incentive count
|
|
*/
|
|
cmd.CommandText = "SELECT COUNT(*) " +
|
|
"FROM reservations " +
|
|
"WHERE (DATE(@Date) BETWEEN StartDate AND EndDate) AND Status in (@Status1,@Status2) AND Type = @Type;";
|
|
cmd.Parameters.AddWithValue("@Date", dt.AddDays(i).Date.ToString("yyyy-MM-dd"));
|
|
cmd.Parameters.AddWithValue("@Status1", (int)ReservationStatus.Active);
|
|
cmd.Parameters.AddWithValue("@Status2", (int)ReservationStatus.Changed);
|
|
cmd.Parameters.AddWithValue("@Type", (int)ReservationType.Incentive);
|
|
|
|
using SQLiteDataReader reader = cmd.ExecuteReader();
|
|
reader.Read();
|
|
if (reader.HasRows && !reader.IsDBNull(0))
|
|
{
|
|
incentive = reader.GetInt32(0);
|
|
}
|
|
else
|
|
{
|
|
incentive = 0;
|
|
}
|
|
}
|
|
Transaction.Commit(); // Commit transaction to database
|
|
}
|
|
occData.Add((dt.AddDays(i), rooms, conventional, prepaid, sixty, incentive));
|
|
}
|
|
}
|
|
return (thirtyDayOcc / days, occData);
|
|
}
|
|
internal static (int, bool) AvgOccupancySpan(DateTime Start, DateTime End)
|
|
{
|
|
/*
|
|
* This query gets the average occupancy and also reports if there was a
|
|
* max capacity found within those 30 days. The count is averaged and returned
|
|
* with the boolean value once all reservation queries are checked to match
|
|
* the critiera. The search criteria is any active/ changed date where the
|
|
* date specified is between the start and end date of any matching reservation.
|
|
*/
|
|
int thirtyDayOcc = 0;
|
|
bool maxCapacityInRange = false;
|
|
int days = (int)(End.Date - Start.Date).TotalDays;
|
|
using (Database Manager = new()) // Create a new database connection
|
|
{
|
|
for (int i = 0; i < days; i++)
|
|
{
|
|
using SQLiteCommand cmd = Manager.con.CreateCommand(); // Create a new command
|
|
cmd.CommandText = $@"SELECT COUNT(*)
|
|
FROM reservations
|
|
WHERE (DATE(@Date) BETWEEN StartDate AND EndDate) AND Status in (@Status1,@Status2);";
|
|
cmd.Parameters.AddWithValue("@Date", Start.AddDays(i).Date.ToString("yyyy-MM-dd"));
|
|
cmd.Parameters.AddWithValue("@Status1", (int)ReservationStatus.Active);
|
|
cmd.Parameters.AddWithValue("@Status2", (int)ReservationStatus.Changed);
|
|
|
|
using SQLiteDataReader reader = cmd.ExecuteReader(); // Create a new SQL data reader
|
|
reader.Read();
|
|
if (reader.HasRows && !reader.IsDBNull(0))
|
|
{
|
|
thirtyDayOcc += reader.GetInt32(0);
|
|
if (reader.GetInt32(0) == 45)
|
|
{
|
|
maxCapacityInRange = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return (thirtyDayOcc / days, maxCapacityInRange);
|
|
}
|
|
internal static Guest? GetGuestByEmail(string Email)
|
|
{
|
|
/*
|
|
* This function searches the database for a guest based off
|
|
* the specified email. If a match is found the guest model is created and returned.
|
|
* If no guest details are found, a null object is returned.
|
|
*/
|
|
Guest? g = null;
|
|
using (Database Manager = new()) // Creates a new database connection
|
|
{
|
|
using SQLiteCommand cmd = Manager.con.CreateCommand(); // Creates a new database command
|
|
cmd.CommandText = $"SELECT * FROM guests WHERE Email = @Email";
|
|
cmd.Parameters.AddWithValue("@Email", Email);
|
|
using SQLiteDataReader reader = cmd.ExecuteReader(); // Creates a new SQL data reader
|
|
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(reader.GetInt32(0), reader.GetString(1), reader.GetString(2), reader.GetString(3), CreditCard, Expiration, CCV); // Create a guest model
|
|
}
|
|
}
|
|
return g;
|
|
}
|
|
internal static Reservation? GetResByGuest(Guest g)
|
|
{
|
|
/*
|
|
* This query gets a reservation by taking an existing guest as the "where" comparison.
|
|
* Since the guest model is already passed into this query, there is no need to join the
|
|
* guests table. Instead only the transaction and reservation details need to be populated
|
|
* and then the guest object is passed into the creation of a reservation object.
|
|
*/
|
|
Reservation? r = null;
|
|
Transaction? t;
|
|
using (Database Manager = new()) // Opens a database connection
|
|
{
|
|
using SQLiteCommand cmd = Manager.con.CreateCommand(); // Creates a new command
|
|
int? RoomNumber = null;
|
|
DateTime? CheckIn = null, CheckOut = null, DateChanged = null, LastPaid = null, PaidOn = null;
|
|
|
|
cmd.CommandText = @"SELECT * FROM reservations
|
|
INNER JOIN transactions ON reservations.TransactionID = transactions.ID
|
|
WHERE GuestID = @GuestID AND Status IN (@Status1,@Status2);";
|
|
cmd.Parameters.AddWithValue("@GuestID", g.Id);
|
|
cmd.Parameters.AddWithValue("@Status1", (int)ReservationStatus.Active);
|
|
cmd.Parameters.AddWithValue("@Status2", (int)ReservationStatus.Changed);
|
|
|
|
using SQLiteDataReader reader = cmd.ExecuteReader(); // Creates a new SQL data reader
|
|
reader.Read();
|
|
if (reader.HasRows)
|
|
{
|
|
if (reader[21].GetType() != typeof(DBNull))
|
|
{
|
|
LastPaid = reader.GetDateTime(21);
|
|
}
|
|
|
|
if (reader[22].GetType() != typeof(DBNull))
|
|
{
|
|
PaidOn = reader.GetDateTime(22);
|
|
}
|
|
|
|
t = new(reader.GetInt32(13), reader.GetDouble(14), reader.GetDouble(15), reader.GetDouble(17), reader.GetDateTime(20), // Creates a new transaction model
|
|
LastPaid: LastPaid, PaidOn: PaidOn, RefundAmount: reader.GetDouble(18), Penalty: reader.GetDouble(16), AmountPaid: reader.GetDouble(19));
|
|
|
|
if (reader[1].GetType() != typeof(DBNull))
|
|
{
|
|
RoomNumber = reader.GetInt32(1);
|
|
}
|
|
|
|
if (reader[10].GetType() != typeof(DBNull))
|
|
{
|
|
CheckIn = reader.GetDateTime(10);
|
|
}
|
|
|
|
if (reader[11].GetType() != typeof(DBNull))
|
|
{
|
|
CheckOut = reader.GetDateTime(11);
|
|
}
|
|
|
|
if (reader[12].GetType() != typeof(DBNull))
|
|
{
|
|
DateChanged = reader.GetDateTime(12);
|
|
}
|
|
|
|
r = new(reader.GetInt32(0), g, t, (ReservationType)reader.GetInt32(5), (ReservationStatus)reader.GetInt32(6), // Creates a new reservation model
|
|
reader.GetDateTime(7), reader.GetDateTime(8), reader.GetDateTime(9), RoomNum: RoomNumber, IsNoShow: reader.GetBoolean(4),
|
|
CheckIn: CheckIn, CheckOut: CheckOut, DateChanged: DateChanged);
|
|
}
|
|
}
|
|
return r;
|
|
}
|
|
internal static TimeRefs? CanBeCheckedIn(string Email)
|
|
{
|
|
/*
|
|
* This query checks to see if a guest can be checked in. Guest are only
|
|
* permitted to check in on the day that their reservation is due to start.
|
|
* If they check in to early, the appropriate TimeRef enum is returned to.
|
|
*/
|
|
TimeRefs? status = null;
|
|
using (Database Manager = new()) // Opens a database connection
|
|
{
|
|
using SQLiteCommand cmd = Manager.con.CreateCommand(); // Creates a new command
|
|
cmd.CommandText = $"SELECT * FROM reservation WHERE Email = @Email AND Status IN (@Status1,@Status2)";
|
|
cmd.Parameters.AddWithValue("@Email", Email);
|
|
using SQLiteDataReader reader = cmd.ExecuteReader(); // Creates a new SQL data reader
|
|
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()
|
|
{
|
|
/*
|
|
* This function is used to get the current base rate that is configured
|
|
* to be the default.
|
|
*/
|
|
double? rate;
|
|
using (Database Manager = new()) // Opens a database connection
|
|
{
|
|
using SQLiteCommand cmd = Manager.con.CreateCommand(); // Creates a new command
|
|
string query = "SELECT Rate FROM rates WHERE DefaultRate = 1;";
|
|
cmd.CommandText = query;
|
|
using SQLiteDataReader reader = cmd.ExecuteReader(); // Creates a new SQL data reader
|
|
reader.Read();
|
|
if (reader.HasRows)
|
|
{
|
|
rate = reader.GetDouble(0);
|
|
}
|
|
else
|
|
{
|
|
rate = null;
|
|
}
|
|
}
|
|
return rate;
|
|
}
|
|
internal static bool GetBaseRateByDate(DateTime dt)
|
|
{
|
|
/*
|
|
* Gets the base rate by a specific date. This is typically used to check
|
|
* if there is a conflicting rate for a given day and return if a rate has
|
|
* been configured for that date.
|
|
*/
|
|
bool configured;
|
|
using (Database Manager = new()) // Opens a database connection
|
|
{
|
|
using SQLiteCommand cmd = Manager.con.CreateCommand(); // Creates a new command
|
|
string query = "SELECT Rate FROM rates WHERE DateSet = @Date;";
|
|
cmd.CommandText = query;
|
|
cmd.Parameters.AddWithValue("@Date", dt.ToString("yyyy-MM-dd"));
|
|
using SQLiteDataReader reader = cmd.ExecuteReader(); // Creates a new SQL data reader
|
|
reader.Read();
|
|
if (reader.HasRows)
|
|
{
|
|
configured = true;
|
|
}
|
|
else
|
|
{
|
|
configured = false;
|
|
}
|
|
}
|
|
return configured;
|
|
}
|
|
internal static void SetBaseRate(double Rate, DateTime DateSet, bool? DefaultRate = null)
|
|
{
|
|
|
|
/*
|
|
* This function is used to create a new base rate in the database and have the option to make it
|
|
* the default base rate.
|
|
*/
|
|
using Database Manager = new(); // Create a new database connection
|
|
using SQLiteCommand cmd = Manager.con.CreateCommand(); // Create a new command
|
|
string query = $"INSERT INTO rates (Rate, DateSet, DefaultRate) VALUES (@Rate, @DateSet, @DefaultRate);";
|
|
cmd.CommandText = query;
|
|
cmd.Parameters.AddWithValue("@Rate", Rate);
|
|
cmd.Parameters.AddWithValue("@DateSet", DateSet.ToString("yyyy-MM-dd"));
|
|
if (DefaultRate != null)
|
|
{
|
|
if (DefaultRate.Value == true)
|
|
{
|
|
cmd.Parameters.AddWithValue("@DefaultRate", Convert.ToInt32(DefaultRate));
|
|
}
|
|
else
|
|
{
|
|
cmd.Parameters.AddWithValue("@DefaultRate", null);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
cmd.Parameters.AddWithValue("@DefaultRate", null);
|
|
}
|
|
cmd.ExecuteNonQuery();
|
|
}
|
|
internal static void UpdateBaseRate(double Rate, DateTime DateSet, bool? DefaultRate = null)
|
|
{
|
|
/*
|
|
* This command is used to update the base rate for an existing base rate.
|
|
* It will replace the value of any rate, including the default rate if specified.
|
|
*/
|
|
using Database Manager = new(); // Create a new database connection
|
|
using SQLiteCommand cmd = Manager.con.CreateCommand(); // Create a new command
|
|
if (DefaultRate != null)
|
|
{
|
|
if (DefaultRate.Value == true)
|
|
{
|
|
cmd.CommandText = $"UPDATE rates SET rate = @Rate, defaultrate = @DefaultRate WHERE DateSet = @Date;";
|
|
cmd.Parameters.AddWithValue("@DefaultRate", Convert.ToInt32(DefaultRate)); // Replaces existing rate
|
|
}
|
|
else
|
|
{
|
|
cmd.CommandText = $"UPDATE rates SET rate = @Rate WHERE DateSet = @Date;";
|
|
}
|
|
}
|
|
else
|
|
{
|
|
cmd.CommandText = $"UPDATE rates SET rate = @Rate WHERE DateSet = @Date;";
|
|
}
|
|
cmd.Parameters.AddWithValue("@Rate", Rate);
|
|
cmd.Parameters.AddWithValue("@Date", DateSet.ToString("yyyy-MM-dd"));
|
|
cmd.ExecuteNonQuery();
|
|
}
|
|
internal static bool CheckBaseRate()
|
|
{
|
|
/*
|
|
* This function is used to check and update if there is a new base rate.
|
|
* It will check to see if there is a base rate set for the current day
|
|
* and if that is the case it will set that as the new DefaultRate to use, 1,
|
|
* while setting the other one to 0.
|
|
*/
|
|
int? OldId = null;
|
|
bool Success = true;
|
|
using (Database Manager = new()) // Open a new database connection
|
|
{
|
|
using (SQLiteCommand cmd = Manager.con.CreateCommand()) // Create a new command
|
|
{
|
|
/*
|
|
* This query checks for the existing default base rate, if it does not find a rate
|
|
* and returns null, then the function will report a boolean value of false.
|
|
*/
|
|
string query = "SELECT Id FROM rates WHERE DefaultRate = 1;";
|
|
cmd.CommandText = query;
|
|
using SQLiteDataReader reader = cmd.ExecuteReader(); // Create a new SQL data reader
|
|
reader.Read();
|
|
if (reader.HasRows)
|
|
{
|
|
OldId = reader.GetInt32(0);
|
|
}
|
|
}
|
|
int? Id;
|
|
if (OldId != null)
|
|
{
|
|
using (SQLiteCommand cmd = Manager.con.CreateCommand()) // Create a new command
|
|
{
|
|
/*
|
|
* This query selects a base rate configured to the current date
|
|
* if it is set. If there is an Id, it will be used in the
|
|
* next query for swapping. No swap occurs if it does not exist.
|
|
*/
|
|
string query = "SELECT Id FROM rates WHERE DateSet = @Date;";
|
|
cmd.CommandText = query;
|
|
cmd.Parameters.AddWithValue("@Date", DateTime.Now.Date.ToString("yyyy-MM-dd"));
|
|
using SQLiteDataReader reader = cmd.ExecuteReader(); // Create a new SQL data reader
|
|
reader.Read();
|
|
if (reader.HasRows)
|
|
{
|
|
Id = reader.GetInt32(0);
|
|
}
|
|
else
|
|
{
|
|
Id = null;
|
|
}
|
|
}
|
|
if (Id != null)
|
|
{
|
|
/*
|
|
* This query swaps the default indicator of the old base rate with the new base
|
|
* rate.
|
|
*/
|
|
using SQLiteCommand cmd = Manager.con.CreateCommand(); // Create a new command
|
|
cmd.CommandText = @"UPDATE rates SET DefaultRate = NULL WHERE Id = @OldID;
|
|
UPDATE rates SET DefaultRate = 1 WHERE Id = @ID;";
|
|
cmd.Parameters.AddWithValue("@OldID", OldId);
|
|
cmd.Parameters.AddWithValue("@ID", Id);
|
|
cmd.ExecuteNonQuery();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Success = false;
|
|
}
|
|
}
|
|
return Success;
|
|
}
|
|
internal static int? CheckInGuest(string Email, DateTime CheckIn)
|
|
{
|
|
/*
|
|
* This query is used to check in a guest and is a multi-part query
|
|
* with several updates to the database. Here the database tables
|
|
* reservation and room will be updated based on whichever
|
|
* room is available, not occupied, and then assigned to the reservation.
|
|
* Once this is complete, the updated information is saved to the database
|
|
* and the room number is returned.
|
|
*/
|
|
int? RoomID = null;
|
|
using (Database Manager = new()) // Opens a new database connection
|
|
{
|
|
using SQLiteTransaction Transaction = Manager.con.BeginTransaction(); // Begin a new SQL transaction
|
|
using (SQLiteCommand cmd = Manager.con.CreateCommand()) // Creates a new command
|
|
{
|
|
/*
|
|
* This query looks at the rooms table for the first instance of an unoccupied
|
|
* room. This room is then set as the reservations associated room.
|
|
*/
|
|
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()) // Creates a new command
|
|
{
|
|
/*
|
|
* This query sets the room that is assigned to the reservation as
|
|
* occupied as a guest has been assigned it.
|
|
*/
|
|
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()) // Creates a new command
|
|
{
|
|
/*
|
|
* This query looks for the room number that was assigned as a result of the queries above.
|
|
* This room number is then stored so it can be returned.
|
|
*/
|
|
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);
|
|
using SQLiteDataReader reader = cmd.ExecuteReader(); // Creates a new SQL reader
|
|
reader.Read();
|
|
if (reader.HasRows)
|
|
{
|
|
RoomID = (int)reader.GetValue(0);
|
|
}
|
|
}
|
|
Transaction.Commit(); // Commits the transaction
|
|
}
|
|
return RoomID;
|
|
}
|
|
internal static bool GuestCurrentlyCheckedIn(string Email)
|
|
{
|
|
/*
|
|
* Checks if a guest is currently checked in. If there is a check-in date
|
|
* on their reservation, that means thay have been checked in. A boolean
|
|
* value is returned whether or not a matching reservation is found.
|
|
*/
|
|
bool EntryFound;
|
|
using (Database Manager = new()) // Creates a new database connection
|
|
{
|
|
using SQLiteCommand cmd = Manager.con.CreateCommand(); // Creates a new command
|
|
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);
|
|
using SQLiteDataReader reader = cmd.ExecuteReader(); // Creates a new SQL data reader
|
|
reader.Read();
|
|
if (reader.HasRows)
|
|
{
|
|
EntryFound = true;
|
|
}
|
|
else
|
|
{
|
|
EntryFound = false;
|
|
}
|
|
}
|
|
return EntryFound;
|
|
}
|
|
internal static void CheckOutGuest(string Email, DateTime CheckOut)
|
|
{
|
|
/*
|
|
* This function checks a guest out given that they have already checked in
|
|
* and have an active reservation. If this criteria is not met, a reservation
|
|
* will not be checked out. If a reservation does match this criteria, the reservation
|
|
* check-out date is set and the status of the reservation is changed to Ended.
|
|
*/
|
|
using Database Manager = new(); // Creates a new database connection
|
|
using SQLiteTransaction Transaction = Manager.con.BeginTransaction(); // Creates a new SQL data reader
|
|
using (SQLiteCommand cmd = Manager.con.CreateCommand()) // Creates a new command
|
|
{
|
|
/*
|
|
* This query looks for the room that is checked in and marks them as unoccupied
|
|
* based on the corresponding room to reservation relation.
|
|
*/
|
|
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) 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 (SQLiteCommand cmd = Manager.con.CreateCommand()) // Creates a new command
|
|
{
|
|
/*
|
|
* This query updates the reservation status as Ended adn the checkout date.
|
|
*/
|
|
cmd.CommandText = "UPDATE reservations SET CheckOut = @Date, Status = @Status " +
|
|
"WHERE GuestID = (SELECT ID FROM guests WHERE Email = @Email) AND RoomNum IS NOT NULL AND Status in (@SActive,@SChanged) AND CheckIn IS NOT NULL;";
|
|
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<Reservation> GetActiveSixtyDayRes()
|
|
{
|
|
/*
|
|
* This query is used to build a list of active 60-day-in-advance reservations
|
|
* and return them all as a list.
|
|
*/
|
|
List<Reservation> list = new();
|
|
using (Database Manager = new()) // Create a new database connection
|
|
{
|
|
using SQLiteCommand cmd = Manager.con.CreateCommand(); // Create a new command
|
|
/*
|
|
* This query will find any reservation with the 60-day type that is Active or Changed
|
|
* and return them all in a table
|
|
*/
|
|
cmd.CommandText = "SELECT * FROM reservations " +
|
|
"INNER JOIN transactions ON reservations.TransactionID = transactions.ID " +
|
|
"INNER JOIN guests ON reservations.GuestID = guests.ID " +
|
|
"WHERE Type = @Type AND Status IN (@Status1,@Status2);";
|
|
cmd.Parameters.AddWithValue("@Type", (int)ReservationType.SixtyDayAdvance);
|
|
cmd.Parameters.AddWithValue("@Status1", (int)ReservationStatus.Active);
|
|
cmd.Parameters.AddWithValue("@Status2", (int)ReservationStatus.Changed);
|
|
using SQLiteDataReader reader = cmd.ExecuteReader(); // Create a new SQL data reader
|
|
while (reader.Read())
|
|
{
|
|
Reservation? r;
|
|
Transaction? t;
|
|
Guest g;
|
|
int? RoomNumber = null;
|
|
DateTime? CheckIn = null, CheckOut = null, DateChanged = null, LastPaid = null, PaidOn = null;
|
|
if (reader.HasRows)
|
|
{
|
|
/*
|
|
* Since we cannot get by string keys, each column is represented by a numerical value
|
|
* like an array. The column is as follows:
|
|
*
|
|
* 0. ID (reservations.ID)
|
|
* 1. RoomNum
|
|
* 2. GuestID
|
|
* 3. TransactionID
|
|
* 4. IsNoShow
|
|
* 5. Type
|
|
* 6. Status
|
|
* 7. CreationDate
|
|
* 8. StartDate
|
|
* 9. EndDate
|
|
* 10. CheckIn
|
|
* 11. CheckOut
|
|
* 12. DateChanged
|
|
* 13. ID (rooms.ID)
|
|
* 14. Rate
|
|
* 15. Owed
|
|
* 16. Penalty
|
|
* 17. Multiplier
|
|
* 18. RefundAmount
|
|
* 19. AmountPaid
|
|
* 20. PayBy
|
|
* 21. LastPaid
|
|
* 22. PaidOn
|
|
* 23. ID (guests.ID)
|
|
* 24. Fname
|
|
* 25. Lname
|
|
* 26. Email
|
|
* 27. CreditCard
|
|
* 28. Expiration
|
|
* 29. CCV
|
|
*
|
|
*/
|
|
if (reader[21].GetType() != typeof(DBNull))
|
|
{
|
|
LastPaid = reader.GetDateTime(21);
|
|
}
|
|
|
|
if (reader[22].GetType() != typeof(DBNull))
|
|
{
|
|
PaidOn = reader.GetDateTime(22);
|
|
}
|
|
|
|
t = new(reader.GetInt32(13), reader.GetDouble(14), reader.GetDouble(15), reader.GetDouble(17), reader.GetDateTime(20), // Creates a new transaction model
|
|
LastPaid: LastPaid, PaidOn: PaidOn, RefundAmount: reader.GetDouble(18), Penalty: reader.GetDouble(16), AmountPaid: reader.GetDouble(19));
|
|
|
|
g = new(reader.GetInt32(23), reader.GetString(24), reader.GetString(25), reader.GetString(26), reader.GetString(27), reader.GetString(28), reader.GetString(29)); // Creates a new guest model
|
|
|
|
if (reader[1].GetType() != typeof(DBNull))
|
|
{
|
|
RoomNumber = reader.GetInt32(1);
|
|
}
|
|
|
|
if (reader[10].GetType() != typeof(DBNull))
|
|
{
|
|
CheckIn = reader.GetDateTime(10);
|
|
}
|
|
|
|
if (reader[11].GetType() != typeof(DBNull))
|
|
{
|
|
CheckOut = reader.GetDateTime(11);
|
|
}
|
|
|
|
if (reader[12].GetType() != typeof(DBNull))
|
|
{
|
|
DateChanged = reader.GetDateTime(12);
|
|
}
|
|
|
|
r = new(reader.GetInt32(0), g, t, (ReservationType)reader.GetInt32(5), (ReservationStatus)reader.GetInt32(6),
|
|
reader.GetDateTime(7), reader.GetDateTime(8), reader.GetDateTime(9), RoomNum: RoomNumber, IsNoShow: reader.GetBoolean(4),
|
|
CheckIn: CheckIn, CheckOut: CheckOut, DateChanged: DateChanged);
|
|
list.Add(r);
|
|
}
|
|
}
|
|
}
|
|
return list;
|
|
}
|
|
internal static List<Reservation> GetPastDueReservations()
|
|
{
|
|
/*
|
|
* This function gets any reservation that is past due.
|
|
* Past due is considered to be any reservation where the start date is
|
|
* older than the current date, the reservation is active or changed, and
|
|
* has not been checked in. This list is then returned.
|
|
*/
|
|
List<Reservation> list = new();
|
|
using (Database Manager = new()) // Create a new database connection
|
|
{
|
|
using SQLiteTransaction Transaction = Manager.con.BeginTransaction(); // Create a new SQL transaction
|
|
using (SQLiteCommand cmd = Manager.con.CreateCommand()) // Create a new command
|
|
{
|
|
/*
|
|
* This query selects non-checked in active and changed reeservations where
|
|
* the start date is older than the current day. These are considered no-shows.
|
|
*/
|
|
cmd.CommandText = "SELECT * FROM reservations " +
|
|
"INNER JOIN transactions ON reservations.TransactionID = transactions.ID " +
|
|
"INNER JOIN guests ON reservations.GuestID = guests.ID " +
|
|
"WHERE DATE(@Date) > StartDate AND Status IN (@Status1,@Status2) AND CheckIn IS NULL;";
|
|
cmd.Parameters.AddWithValue("@Date", DateTime.Now.Date.ToString("yyyy-MM-dd"));
|
|
cmd.Parameters.AddWithValue("@Status1", (int)ReservationStatus.Active);
|
|
cmd.Parameters.AddWithValue("@Status2", (int)ReservationStatus.Changed);
|
|
using SQLiteDataReader reader = cmd.ExecuteReader(); // Create a new SQL data reader
|
|
while (reader.Read())
|
|
{
|
|
Reservation? r;
|
|
Transaction? t;
|
|
Guest g;
|
|
int? RoomNumber = null;
|
|
DateTime? CheckIn = null, CheckOut = null, DateChanged = null, LastPaid = null, PaidOn = null;
|
|
if (reader.HasRows)
|
|
{
|
|
/*
|
|
* Since we cannot get by string keys, each column is represented by a numerical value
|
|
* like an array. The column is as follows:
|
|
*
|
|
* 0. ID (reservations.ID)
|
|
* 1. RoomNum
|
|
* 2. GuestID
|
|
* 3. TransactionID
|
|
* 4. IsNoShow
|
|
* 5. Type
|
|
* 6. Status
|
|
* 7. CreationDate
|
|
* 8. StartDate
|
|
* 9. EndDate
|
|
* 10. CheckIn
|
|
* 11. CheckOut
|
|
* 12. DateChanged
|
|
* 13. ID (rooms.ID)
|
|
* 14. Rate
|
|
* 15. Owed
|
|
* 16. Penalty
|
|
* 17. Multiplier
|
|
* 18. RefundAmount
|
|
* 19. AmountPaid
|
|
* 20. PayBy
|
|
* 21. LastPaid
|
|
* 22. PaidOn
|
|
* 23. ID (guests.ID)
|
|
* 24. Fname
|
|
* 25. Lname
|
|
* 26. Email
|
|
* 27. CreditCard
|
|
* 28. Expiration
|
|
* 29. CCV
|
|
*
|
|
*/
|
|
if (reader[21].GetType() != typeof(DBNull))
|
|
{
|
|
LastPaid = reader.GetDateTime(21);
|
|
}
|
|
|
|
if (reader[22].GetType() != typeof(DBNull))
|
|
{
|
|
PaidOn = reader.GetDateTime(22);
|
|
}
|
|
|
|
t = new(reader.GetInt32(13), reader.GetDouble(14), reader.GetDouble(15), reader.GetDouble(17), reader.GetDateTime(20), // Create a new transaction model
|
|
LastPaid: LastPaid, PaidOn: PaidOn, RefundAmount: reader.GetDouble(18), Penalty: reader.GetDouble(16), AmountPaid: reader.GetDouble(19));
|
|
|
|
g = new(reader.GetInt32(23), reader.GetString(24), reader.GetString(25), reader.GetString(26), reader.GetString(27), reader.GetString(28), reader.GetString(29)); // Create a new guest model
|
|
|
|
if (reader[1].GetType() != typeof(DBNull))
|
|
{
|
|
RoomNumber = reader.GetInt32(1);
|
|
}
|
|
|
|
if (reader[10].GetType() != typeof(DBNull))
|
|
{
|
|
CheckIn = reader.GetDateTime(10);
|
|
}
|
|
|
|
if (reader[11].GetType() != typeof(DBNull))
|
|
{
|
|
CheckOut = reader.GetDateTime(11);
|
|
}
|
|
|
|
if (reader[12].GetType() != typeof(DBNull))
|
|
{
|
|
DateChanged = reader.GetDateTime(12);
|
|
}
|
|
|
|
r = new(reader.GetInt32(0), g, t, (ReservationType)reader.GetInt32(5), (ReservationStatus)reader.GetInt32(6), // Create a new reservation model
|
|
reader.GetDateTime(7), reader.GetDateTime(8), reader.GetDateTime(9), RoomNum: RoomNumber, IsNoShow: reader.GetBoolean(4),
|
|
CheckIn: CheckIn, CheckOut: CheckOut, DateChanged: DateChanged);
|
|
list.Add(r);
|
|
}
|
|
}
|
|
}
|
|
using (SQLiteCommand cmd = Manager.con.CreateCommand())
|
|
{
|
|
/*
|
|
* This query updates reservations where the same criteria above is matched and then
|
|
* no-show is set. At some point the order of these queries should be swapped as the first
|
|
* can be simplified if we update the table first.
|
|
*/
|
|
cmd.CommandText = "UPDATE reservations SET IsNoShow = 1, DateChanged = @DateChanged " +
|
|
"WHERE DATE (@Date) > StartDate AND Status IN (@Status1,@Status2) AND CheckIn IS NULL";
|
|
cmd.Parameters.AddWithValue("@Date", DateTime.Now.Date.ToString("yyyy-MM-dd"));
|
|
cmd.Parameters.AddWithValue("@DateChanged", DateTime.Now.Date.ToString("yyyy-MM-dd"));
|
|
cmd.Parameters.AddWithValue("@Status1", (int)ReservationStatus.Active);
|
|
cmd.Parameters.AddWithValue("@Status2", (int)ReservationStatus.Changed);
|
|
cmd.ExecuteNonQuery();
|
|
}
|
|
Transaction.Commit(); // Commits the transaction
|
|
}
|
|
return list;
|
|
}
|
|
}
|
|
internal enum TimeRefs // Numerical values represented as words
|
|
{
|
|
OnTime,
|
|
Early,
|
|
Late
|
|
}
|
|
}
|