Codenew
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
namespace TrainTicketBookingSystem
{
// User Class to store User related data
public class User
{
public int UserID { get; set; }
public string Username { get; set; }
public string Password { get; set; }
public string Email { get; set; }
public string Role { get; set; } // "Admin" or "Customer"
}
// Train Class to store Train related data
public class Train
{
public int TrainNumber { get; set; }
public string TrainName { get; set; }
public string Origin { get; set; }
public string Destination { get; set; }
public DateTime DepartureTime { get; set; }
public DateTime ArrivalTime { get; set; }
public int TotalSeats { get; set; }
}
// Booking Class to store Booking related data
public class Booking
{
public int BookingID { get; set; }
public int CustomerID { get; set; }
public int TrainNumber { get; set; }
public DateTime BookingDate { get; set; }
public List<int> SeatNumbers { get; set; } // Changed to List<int> to store multiple seats
public decimal Fare { get; set; }
public string BookingStatus { get; set; } // e.g., "Booked", "Cancelled"
}
// Passenger Class to store Passenger related data.
public class Passenger
{
public string Name { get; set; }
public int Age { get; set; }
public string Gender { get; set; }
}
// UserRepository Class to manage User data
public class UserRepository
{
private static List<User> users = new List<User>();
private static int nextUserId = 1;
public static void AddUser(User user)
{
user.UserID = nextUserId++;
users.Add(user);
}
public static User GetUserByUsername(string username)
{
return users.FirstOrDefault(u => u.Username == username);
}
public static User GetUserById(int id)
{
return users.FirstOrDefault(u => u.UserID == id);
}
}
// TrainRepository Class to manage Train data
public class TrainRepository
{
private static List<Train> trains = new List<Train>();
public static void AddTrain(Train train)
{
trains.Add(train);
}
public static Train GetTrainByNumber(int trainNumber)
{
return trains.FirstOrDefault(t => t.TrainNumber == trainNumber);
}
public static List<Train> SearchTrains(string origin, string destination, DateTime departureDate)
{
return trains.Where(t => t.Origin.Equals(origin, StringComparison.OrdinalIgnoreCase)
&& t.Destination.Equals(destination, StringComparison.OrdinalIgnoreCase)
&& t.DepartureTime.Date == departureDate.Date).ToList();
}
public static List<Train> GetAllTrains()
{
return trains;
}
public static void UpdateTrain(Train train)
{
Train existingTrain = GetTrainByNumber(train.TrainNumber);
if (existingTrain != null)
{
existingTrain.TrainName = train.TrainName;
existingTrain.Origin = train.Origin;
existingTrain.Destination = train.Destination;
existingTrain.DepartureTime = train.DepartureTime;
existingTrain.ArrivalTime = train.ArrivalTime;
existingTrain.TotalSeats = train.TotalSeats;
}
}
}
// BookingRepository Class to manage Booking data
public class BookingRepository
{
private static List<Booking> bookings = new List<Booking>();
private static int nextBookingId = 1;
public static void AddBooking(Booking booking)
{
booking.BookingID = nextBookingId++;
bookings.Add(booking);
}
public static Booking GetBookingById(int bookingId)
{
return bookings.FirstOrDefault(b => b.BookingID == bookingId);
}
public static List<Booking> GetBookingsByUserId(int userId)
{
return bookings.Where(b => b.CustomerID == userId).ToList();
}
public static void UpdateBooking(Booking booking)
{
Booking existingBooking = GetBookingById(booking.BookingID);
if (existingBooking != null)
{
existingBooking.BookingStatus = booking.BookingStatus;
}
}
public static List<Booking> GetBookingsByTrainNumberAndDate(int trainNumber, DateTime bookingDate)
{
return bookings.Where(b => b.TrainNumber == trainNumber && b.BookingDate.Date == bookingDate.Date).ToList();
}
}
// Main Class containing the program's entry point and implementation of the user stories
public class TrainTicketBookingSystem
{
private static User loggedInUser = null;
private static List<Passenger> passengers = new List<Passenger>(); // List of passengers for current booking
public static void Main(string[] args)
{
// Seed data for testing. Added more train data for comprehensive testing.
SeedData();
// Ask for the user's role first
Console.WriteLine("Welcome to the Train Ticket Booking System!");
Console.WriteLine("Are you a:");
Console.WriteLine("1. Admin");
Console.WriteLine("2. New User");
Console.WriteLine("3. Already Registered User");
Console.Write("Enter your choice (1, 2, or 3): ");
string roleChoice = Console.ReadLine();
switch (roleChoice)
{
case "1":
loggedInUser = new User { Role = "Admin" }; // Simulate admin login
break;
case "2":
RegisterUser(); // Register the new user and log them in
break;
case "3":
LoginUser(); // Log in the existing user
break;
default:
Console.WriteLine("Invalid choice. Exiting application.");
return;
}
if (loggedInUser == null && roleChoice == "3")
{
Console.WriteLine("Login failed. Exiting Application");
return;
}
// Main application loop
while (true)
{
Console.WriteLine("\nTrain Ticket Booking System");
Console.WriteLine("1. View All Trains (Admin Only)");
Console.WriteLine("2. Add Train (Admin Only)");
Console.WriteLine("3. Update Train (Admin Only)");
Console.WriteLine("4. Search Trains");
Console.WriteLine("5. Book Ticket");
Console.WriteLine("6. View Bookings");
Console.WriteLine("7. Cancel Booking");
Console.WriteLine("8. View Booking History"); // US_PROG_004
Console.WriteLine("9. Sort Trains by Departure Time"); // US_PROG_005
Console.WriteLine("10. Find Trains with Available Seats"); // US_PROG_006
Console.WriteLine("11. Dynamically Allocate Seats"); // US_PROG_007
Console.WriteLine("12. Exit");
Console.Write("Enter your choice: ");
string choice = Console.ReadLine();
switch (choice)
{
case "1":
if (loggedInUser != null && loggedInUser.Role == "Admin")
ViewAllTrains();
else
Console.WriteLine("Unauthorized access.");
break;
case "2":
if (loggedInUser != null && loggedInUser.Role == "Admin")
AddTrain();
else
Console.WriteLine("Unauthorized access.");
break;
case "3":
if (loggedInUser != null && loggedInUser.Role == "Admin")
UpdateTrain();
else
Console.WriteLine("Unauthorized access.");
break;
case "4":
SearchTrains();
break;
case "5":
BookTicket();
break;
case "6":
ViewBookings();
break;
case "7":
CancelBooking();
break;
case "8": // US_PROG_004
ViewBookingHistory();
break;
case "9": // US_PROG_005
SortTrainsByDepartureTime();
break;
case "10": // US_PROG_006
FindTrainsWithAvailableSeats();
break;
case "11": // US_PROG_007
if (loggedInUser == null)
{
Console.WriteLine("Please log in to book a ticket.");
break;
}
Train selectedTrainForAllocation = null;
DateTime bookingDateForAllocation = DateTime.Now;
int numberOfPassengersForAllocation = 0;
Console.Write("Enter train number: ");
if (int.TryParse(Console.ReadLine(), out int trainNumberForAllocation))
{
selectedTrainForAllocation = TrainRepository.GetTrainByNumber(trainNumberForAllocation);
if (selectedTrainForAllocation == null)
{
Console.WriteLine("Train not found.");
break;
}
}
else
{
Console.WriteLine("Invalid Train Number");
break;
}
Console.Write("Enter Booking Date: ");
if (!DateTime.TryParse(Console.ReadLine(), out bookingDateForAllocation))
{
Console.WriteLine("Invalid date format.");
break;
}
Console.Write("Enter Number of Passengers (Max 10): ");
if (!int.TryParse(Console.ReadLine(), out numberOfPassengersForAllocation))
{
Console.WriteLine("Invalid number of passengers.");
break;
}
DynamicallyAllocateSeats(selectedTrainForAllocation, bookingDateForAllocation, numberOfPassengersForAllocation);
break;
case "12":
Console.WriteLine("Exiting application.");
return;
default:
Console.WriteLine("Invalid choice. Please try again.");
break;
}
}
}
// Method to seed initial data (users, trains)
private static void SeedData()
{
// Add some initial users (1 admin, 2 customers)
UserRepository.AddUser(new User { Username = "admin", Password = "password", Email = "[email protected]", Role = "Admin" });
UserRepository.AddUser(new User { Username = "customer1", Password = "password1", Email = "[email protected]", Role = "Customer" });
UserRepository.AddUser(new User { Username = "customer2", Password = "password2", Email = "[email protected]", Role = "Customer" });
// Add some initial trains
TrainRepository.AddTrain(new Train { TrainNumber = 101, TrainName = "ExpressA", Origin = "Mumbai", Destination = "Delhi", DepartureTime = DateTime.Parse("2024-03-10 10:00 AM"), ArrivalTime = DateTime.Parse("2024-03-11 10:00 AM"), TotalSeats = 100 });
TrainRepository.AddTrain(new Train { TrainNumber = 102, TrainName = "SuperFastB", Origin = "Delhi", Destination = "Kolkata", DepartureTime = DateTime.Parse("2024-03-11 08:00 AM"), ArrivalTime = DateTime.Parse("2024-03-12 12:00 PM"), TotalSeats = 120 });
TrainRepository.AddTrain(new Train { TrainNumber = 103, TrainName = "MailC", Origin = "Mumbai", Destination = "Goa", DepartureTime = DateTime.Parse("2024-03-12 06:00 AM"), ArrivalTime = DateTime.Parse("2024-03-12 03:00 PM"), TotalSeats = 80 });
TrainRepository.AddTrain(new Train { TrainNumber = 104, TrainName = "LocalD", Origin = "Kolkata", Destination = "Mumbai", DepartureTime = DateTime.Parse("2024-03-13 09:00 AM"), ArrivalTime = DateTime.Parse("2024-03-14 11:00 AM"), TotalSeats = 150 });
TrainRepository.AddTrain(new Train { TrainNumber = 105, TrainName = "Rajdhani", Origin = "Bangalore", Destination = "Delhi", DepartureTime = DateTime.Parse("2024-03-15 07:00 AM"), ArrivalTime = DateTime.Parse("2024-03-16 09:00 AM"), TotalSeats = 90 });
}
// Method to handle user registration (US001)
private static void RegisterUser()
{
Console.Write("Enter username: ");
string username = Console.ReadLine();
// Check if username already exists
if (UserRepository.GetUserByUsername(username) != null)
{
Console.WriteLine("Username already exists. Please choose a different username.");
return;
}
Console.Write("Enter password: ");
string password = Console.ReadLine();
Console.Write("Enter email: ");
string email = Console.ReadLine();
User newUser = new User
{
Username = username,
Password = password,
Email = email,
Role = "Customer" // Default role is customer
};
UserRepository.AddUser(newUser);
Console.WriteLine("Registration successful. Please log in.");
loggedInUser = newUser; // Log in the new user
}
// Method to handle user login (US002)
private static void LoginUser()
{
Console.Write("Enter username: ");
string username = Console.ReadLine();
Console.Write("Enter password: ");
string password = Console.ReadLine();
User user = UserRepository.GetUserByUsername(username);
if (user != null && user.Password == password)
{
loggedInUser = user;
Console.WriteLine($"Login successful. Welcome, {loggedInUser.Username}!");
}
else
{
Console.WriteLine("Invalid username or password.");
loggedInUser = null;
}
}
// Method to display all trains (Admin Only)
private static void ViewAllTrains()
{
Console.WriteLine("\nAll Trains:");
List<Train> allTrains = TrainRepository.GetAllTrains();
if (allTrains.Count == 0)
{
Console.WriteLine("No trains available.");
return;
}
Console.WriteLine("--------------------------------------------------------------------------------------------------");
Console.WriteLine("Train Number | Train Name | Origin | Destination | Departure Time | Arrival Time | Total Seats");
Console.WriteLine("--------------------------------------------------------------------------------------------------");
foreach (Train train in allTrains)
{
Console.WriteLine($"{train.TrainNumber,-13} | {train.TrainName,-16} | {train.Origin,-10} | {train.Destination,-12} | {train.DepartureTime,-24:f} | {train.ArrivalTime,-24:f} | {train.TotalSeats,-11}");
}
Console.WriteLine("--------------------------------------------------------------------------------------------------");
}
// Method to add a new train (Admin Only) (US003)
private static void AddTrain()
{
Console.Write("Enter train number: ");
if (!int.TryParse(Console.ReadLine(), out int trainNumber))
{
Console.WriteLine("Invalid train number.");
return;
}
if (TrainRepository.GetTrainByNumber(trainNumber) != null)
{
Console.WriteLine("A train with this number already exists.");
return;
}
Console.Write("Enter train name: ");
string trainName = Console.ReadLine();
Console.Write("Enter origin: ");
string origin = Console.ReadLine();
Console.Write("Enter destination: ");
string destination = Console.ReadLine();
Console.Write("Enter departure time (e.g., 2024-03-15 14:30): ");
if (!DateTime.TryParse(Console.ReadLine(), out DateTime departureTime))
{
Console.WriteLine("Invalid date/time format.");
return;
}
Console.Write("Enter arrival time (e.g., 2024-03-15 16:30): ");
if (!DateTime.TryParse(Console.ReadLine(), out DateTime arrivalTime))
{
Console.WriteLine("Invalid date/time format.");
return;
}
Console.Write("Enter total number of seats: ");
if (!int.TryParse(Console.ReadLine(), out int totalSeats))
{
Console.WriteLine("Invalid number of seats.");
return;
}
Train newTrain = new Train
{
TrainNumber = trainNumber,
TrainName = trainName,
Origin = origin,
Destination = destination,
DepartureTime = departureTime,
ArrivalTime = arrivalTime,
TotalSeats = totalSeats
};
TrainRepository.AddTrain(newTrain);
Console.WriteLine("Train added successfully.");
}
// Method to update an existing train (Admin Only) (US003)
private static void UpdateTrain()
{
Console.Write("Enter train number to update: ");
if (!int.TryParse(Console.ReadLine(), out int trainNumberToUpdate))
{
Console.WriteLine("Invalid train number.");
return;
}
Train trainToUpdate = TrainRepository.GetTrainByNumber(trainNumberToUpdate);
if (trainToUpdate == null)
{
Console.WriteLine("Train not found.");
return;
}
Console.Write($"Enter new train name (current: {trainToUpdate.TrainName}): ");
string newTrainName = Console.ReadLine();
if (string.IsNullOrEmpty(newTrainName))
newTrainName = trainToUpdate.TrainName;
Console.Write($"Enter new origin (current: {trainToUpdate.Origin}): ");
string newOrigin = Console.ReadLine();
if (string.IsNullOrEmpty(newOrigin))
newOrigin = trainToUpdate.Origin;
Console.Write($"Enter new destination (current: {trainToUpdate.Destination}): ");
string newDestination = Console.ReadLine();
if (string.IsNullOrEmpty(newDestination))
newDestination = trainToUpdate.Destination;
Console.Write($"Enter new departure time (e.g., 2024-03-15 14:30) (current: {trainToUpdate.DepartureTime:f}): ");
string departureTimeStr = Console.ReadLine();
DateTime newDepartureTime;
if (string.IsNullOrEmpty(departureTimeStr) || !DateTime.TryParse(departureTimeStr, out newDepartureTime))
{
newDepartureTime = trainToUpdate.DepartureTime;
}
Console.Write($"Enter new arrival time (e.g., 2024-03-15 16:30) (current: {trainToUpdate.ArrivalTime:f}): ");
string arrivalTimeStr = Console.ReadLine();
DateTime newArrivalTime;
if (string.IsNullOrEmpty(arrivalTimeStr) || !DateTime.TryParse(arrivalTimeStr, out newArrivalTime))
{
newArrivalTime = trainToUpdate.ArrivalTime;
}
Console.Write($"Enter new total number of seats (current: {trainToUpdate.TotalSeats}): ");
string totalSeatsStr = Console.ReadLine();
int newTotalSeats;
if (string.IsNullOrEmpty(totalSeatsStr) || !int.TryParse(totalSeatsStr, out newTotalSeats))
{
newTotalSeats = trainToUpdate.TotalSeats;
}
Train updatedTrain = new Train
{
TrainNumber = trainToUpdate.TrainNumber,
TrainName = newTrainName,
Origin = newOrigin,
Destination = newDestination,
DepartureTime = newDepartureTime,
ArrivalTime = newArrivalTime,
TotalSeats = newTotalSeats
};
TrainRepository.UpdateTrain(updatedTrain);
Console.WriteLine("Train updated successfully.");
}
// Method to search for trains (US004)
private static void SearchTrains()
{
Console.Write("Enter origin: ");
string origin = Console.ReadLine();
Console.Write("Enter destination: ");
string destination = Console.ReadLine();
Console.Write("Enter departure date (e.g., 2024-03-15): ");
if (!DateTime.TryParse(Console.ReadLine(), out DateTime departureDate))
{
Console.WriteLine("Invalid date format.");
return;
}
List<Train> searchResults = TrainRepository.SearchTrains(origin, destination, departureDate);
if (searchResults.Count == 0)
{
Console.WriteLine("No trains found for the given criteria.");
return;
}
Console.WriteLine("\nSearch Results:");
Console.WriteLine("-----------------------------------------------------------------------------------");
Console.WriteLine("Train Number | Train Name | Departure Time | Arrival Time | Origin | Destination");
Console.WriteLine("-----------------------------------------------------------------------------------");
foreach (Train train in searchResults)
{
Console.WriteLine($"{train.TrainNumber,-13} | {train.TrainName,-16} | {train.DepartureTime,-24:f} | {train.ArrivalTime,-24:f} | {train.Origin,-10} | {train.Destination,-12}");
}
Console.WriteLine("-----------------------------------------------------------------------------------");
// Allow user to view details of a specific train
Console.Write("Enter train number to view details (or 0 to skip): ");
if (!int.TryParse(Console.ReadLine(), out int selectedTrainNumber))
{
Console.WriteLine("Invalid train number.");
return;
}
if (selectedTrainNumber > 0)
{
Train selectedTrain = TrainRepository.GetTrainByNumber(selectedTrainNumber);
if (selectedTrain != null)
{
Console.WriteLine("\nTrain Details:");
Console.WriteLine($"Train Number: {selectedTrain.TrainNumber}");
Console.WriteLine($"Train Name: {selectedTrain.TrainName}");
Console.WriteLine($"Origin: {selectedTrain.Origin}");
Console.WriteLine($"Destination: {selectedTrain.Destination}");
Console.WriteLine($"Departure Time: {selectedTrain.DepartureTime:f}");
Console.WriteLine($"Arrival Time: {selectedTrain.ArrivalTime:f}");
Console.WriteLine($"Total Seats: {selectedTrain.TotalSeats}");
}
else
{
Console.WriteLine("Invalid train number.");
}
}
}
// Method to book a ticket (US005)
private static void BookTicket()
{
if (loggedInUser == null)
{
Console.WriteLine("Please log in to book a ticket.");
return;
}
Console.Write("Enter train number: ");
if (!int.TryParse(Console.ReadLine(), out int trainNumber))
{
Console.WriteLine("Invalid train number.");
return;
}
Train train = TrainRepository.GetTrainByNumber(trainNumber);
if (train == null)
{
Console.WriteLine("Train not found.");
return;
}
Console.Write("Enter booking date (e.g., 2024-03-15): ");
if (!DateTime.TryParse(Console.ReadLine(), out DateTime bookingDate))
{
Console.WriteLine("Invalid date format.");
return;
}
if (bookingDate.Date < DateTime.Now.Date)
{
Console.WriteLine("Booking date cannot be in the past.");
return;
}
//Check for available seats
List<Booking> existingBookings = BookingRepository.GetBookingsByTrainNumberAndDate(trainNumber, bookingDate);
int bookedSeats = existingBookings.Sum(b => b.SeatNumbers.Count);
int availableSeats = train.TotalSeats - bookedSeats;
if (availableSeats <= 0)
{
Console.WriteLine("No seats available on this train for the selected date.");
return;
}
Console.Write("Enter number of passengers: ");
if (!int.TryParse(Console.ReadLine(), out int numberOfPassengers))
{
Console.WriteLine("Invalid number of passengers.");
return;
}
if (numberOfPassengers <= 0)
{
Console.WriteLine("Number of passengers must be greater than zero.");
return;
}
if (numberOfPassengers > availableSeats)
{
Console.WriteLine($"Only {availableSeats} seats available. Please enter a lower number of passengers.");
return;
}
passengers.Clear(); // Clear any previous passenger data
// Get passenger details
for (int i = 0; i < numberOfPassengers; i++)
{
Console.WriteLine($"\nPassenger {i + 1}:");
Console.Write("Enter name: ");
string name = Console.ReadLine();
Console.Write("Enter age: ");
if (!int.TryParse(Console.ReadLine(), out int age))
{
Console.WriteLine("Invalid age. Please enter a valid number.");
return; // Exit the booking process
}
Console.Write("Enter gender: ");
string gender = Console.ReadLine();
passengers.Add(new Passenger { Name = name, Age = age, Gender = gender });
}List<int> selectedSeatNumbers = new List<int>();
// Seat selection
Console.WriteLine($"Available Seats: {availableSeats}");
Console.Write("Enter seat numbers (comma-separated, e.g., 1,2,3):");
string seatNumbersInput = Console.ReadLine();
if (string.IsNullOrEmpty(seatNumbersInput))
{
Console.WriteLine("No seat numbers provided.");
return;
}
string[] seatNumbersArray = seatNumbersInput.Split(',');
foreach (string seatNumberStr in seatNumbersArray)
{
if (int.TryParse(seatNumberStr.Trim(), out int seatNumber))
{
if (seatNumber > 0 && seatNumber <= train.TotalSeats) //Basic seat number validation
{
selectedSeatNumbers.Add(seatNumber);
}
else
{
Console.WriteLine($"Invalid seat number: {seatNumber}. Seat numbers must be between 1 and {train.TotalSeats}.");
return;
}
}
else
{
Console.WriteLine($"Invalid seat number format: {seatNumberStr}.");
return;
}
}
// Check for duplicate seats
if (selectedSeatNumbers.Distinct().Count() != selectedSeatNumbers.Count)
{
Console.WriteLine("Duplicate seat numbers detected. Please select unique seatnumbers.");
return;
}
//Check if the seats are already booked
foreach (int seatNumber in selectedSeatNumbers)
{
if (existingBookings.Any(b => b.SeatNumbers.Contains(seatNumber)))
{
Console.WriteLine($"Seat number {seatNumber} is already booked.");
return;
}
}
if (selectedSeatNumbers.Count != numberOfPassengers)
{
Console.WriteLine($"Number of seats selected ({selectedSeatNumbers.Count}) does not match the number of passengers ({numberOfPassengers}).");
return;
}
decimal fare = selectedSeatNumbers.Count * 100; // Assume a fare of $100 per seat. Can be made more complex.
Booking newBooking = new Booking
{
CustomerID = loggedInUser.UserID,
TrainNumber = trainNumber,
BookingDate = bookingDate,
SeatNumbers = selectedSeatNumbers,
Fare = fare,
BookingStatus = "Booked"
};
BookingRepository.AddBooking(newBooking);
Console.WriteLine($"Booking successful! Your Booking ID is {newBooking.BookingID}.");
Console.WriteLine("Passenger Details:");
for (int i = 0; i < passengers.Count; i++)
{
Console.WriteLine($"- {passengers[i].Name}, Age: {passengers[i].Age}, Gender: {passengers[i].Gender}, Seat Number: {selectedSeatNumbers[i]}");
}
Console.WriteLine($"Total Fare: ${newBooking.Fare}");
}
// Method to view user's bookings (US007)
private static void ViewBookings()
{
if (loggedInUser == null)
{
Console.WriteLine("Please log in to view your bookings.");
return;
}
List<Booking> userBookings = BookingRepository.GetBookingsByUserId(loggedInUser.UserID);
if (userBookings.Count == 0)
{
Console.WriteLine("You have no bookings.");
return;
}
Console.WriteLine("\nYour Bookings:");
Console.WriteLine("---------------------------------------------------------------------------------------------------");
Console.WriteLine("Booking ID | Train Number | Booking Date | Seat Numbers | Fare | Booking Status");
Console.WriteLine("---------------------------------------------------------------------------------------------------");
foreach (Booking booking in userBookings)
{
string seatNumbers = string.Join(",", booking.SeatNumbers); // Convert seat list to string
Console.WriteLine($"{booking.BookingID,-11} | {booking.TrainNumber,-12} | {booking.BookingDate,-16:d} | {seatNumbers,-18} | {booking.Fare,-8} | {booking.BookingStatus,-14}");
}
Console.WriteLine("---------------------------------------------------------------------------------------------------");
}
// Method to cancel a booking (US006)
private static void CancelBooking()
{
if (loggedInUser == null)
{
Console.WriteLine("Please log in to cancel a booking.");
return;
}
Console.Write("Enter booking ID to cancel: ");
if (!int.TryParse(Console.ReadLine(), out int bookingIdToCancel))
{
Console.WriteLine("Invalid booking ID.");
return;
}
Booking bookingToCancel = BookingRepository.GetBookingById(bookingIdToCancel);
if (bookingToCancel == null)
{
Console.WriteLine("Booking not found.");
return;
}
if (bookingToCancel.CustomerID != loggedInUser.UserID)
{
Console.WriteLine("You are not authorized to cancel this booking.");
return;
}
if (bookingToCancel.BookingDate.Date < DateTime.Now.Date)
{
Console.WriteLine("Cannot cancel booking. The departure date has already passed.");
return;
}
if (bookingToCancel.BookingStatus == "Cancelled")
{
Console.WriteLine("This booking has already been cancelled.");
return;
}
Console.Write($"Are you sure you want to cancel booking ID {bookingIdToCancel}? (yes/no): ");
string confirmation = Console.ReadLine().ToLower();
if (confirmation == "yes")
{
bookingToCancel.BookingStatus = "Cancelled"; // Update the booking status
BookingRepository.UpdateBooking(bookingToCancel);
Console.WriteLine("Booking cancelled successfully.");
// Refund logic can be added here
}
else
{
Console.WriteLine("Booking cancellation aborted.");
}
}
// Method to view booking history (US_PROG_004)
private static void ViewBookingHistory()
{
if (loggedInUser == null)
{
Console.WriteLine("Please log in to view your booking history.");
return;
}
Console.Write("Enter customer ID: ");
if (!int.TryParse(Console.ReadLine(), out int customerId))
{
Console.WriteLine("Invalid customer ID.");
return;
}
User customer = UserRepository.GetUserById(customerId);
if (customer == null)
{
Console.WriteLine("Customer ID does not exist in the system.");
return;
}
List<Booking> bookingHistory = BookingRepository.GetBookingsByUserId(customerId);
if (bookingHistory.Count == 0)
{
Console.WriteLine("No booking history found for this customer.");
return;
}
Console.WriteLine("\nBooking History:");
Console.WriteLine("---------------------------------------------------------------------------------------------------");
Console.WriteLine("Booking ID | Train Number | Booking Date | Seat Numbers | Fare | Booking Status");
Console.WriteLine("---------------------------------------------------------------------------------------------------");
foreach (Booking booking in bookingHistory)
{
string seatNumbers = string.Join(",", booking.SeatNumbers);
Console.WriteLine($"{booking.BookingID,-11} | {booking.TrainNumber,-12} | {booking.BookingDate,-16:d} | {seatNumbers,-18} | {booking.Fare,-8} | {booking.BookingStatus,-14}");
}
Console.WriteLine("---------------------------------------------------------------------------------------------------");
}
// Method to view trains sorted by departure time (US_PROG_005)
private static void SortTrainsByDepartureTime()
{
Console.Write("Enter origin station: ");
string origin = Console.ReadLine();
Console.Write("Enter destination station: ");
string destination = Console.ReadLine();
// Basic input validation
if (string.IsNullOrEmpty(origin) || string.IsNullOrEmpty(destination))
{
Console.WriteLine("Origin and Destination stations are required.");
return;
}
List<Train> sortedTrains = TrainRepository.SearchTrains(origin, destination, DateTime.MinValue) // Pass DateTime.MinValue to get all
.OrderBy(t => t.DepartureTime)
.ToList();
if (sortedTrains.Count == 0)
{
Console.WriteLine("No trains found for the given origin and destination.");
return;
}
Console.WriteLine("\nTrains Sorted by Departure Time:");
Console.WriteLine("---------------------------------------------------------------------------------------------------");
Console.WriteLine("Train Number | Train Name | Departure Time | Arrival Time | Origin | Destination");
Console.WriteLine("---------------------------------------------------------------------------------------------------");
foreach (Train train in sortedTrains)
{
Console.WriteLine($"{train.TrainNumber,-13} | {train.TrainName,-16} | {train.DepartureTime,-24:f} | {train.ArrivalTime,-24:f} | {train.Origin,-10} | {train.Destination,-12}");
}
Console.WriteLine("---------------------------------------------------------------------------------------------------");
}
// Method to find trains with available seats (US_PROG_006)
private static void FindTrainsWithAvailableSeats()
{
Console.Write("Enter origin station: ");
string origin = Console.ReadLine();
Console.Write("Enter destination station: ");
string destination = Console.ReadLine();
Console.Write("Enter number of tickets: ");
if (!int.TryParse(Console.ReadLine(), out int numberOfTickets))
{
Console.WriteLine("Invalid number of tickets.");
return;
}
// Basic input validation
if (string.IsNullOrEmpty(origin) || string.IsNullOrEmpty(destination))
{
Console.WriteLine("Origin and Destination stations are required.");
return;
}
if (numberOfTickets <= 0)
{
Console.WriteLine("Number of tickets must be greater than zero.");
return;
}
List<Train> availableTrains = new List<Train>();
List<Train> allTrains = TrainRepository.SearchTrains(origin, destination, DateTime.MinValue); // Get all trains first
foreach (Train train in allTrains)
{
// Calculate available seats for each train
List<Booking> existingBookings = BookingRepository.GetBookingsByTrainNumberAndDate(train.TrainNumber, DateTime.Now); // Consider bookings for today
int bookedSeats = existingBookings.Sum(b => b.SeatNumbers.Count);
int availableSeats = train.TotalSeats - bookedSeats;
if (availableSeats >= numberOfTickets)
{
availableTrains.Add(train);
}
}
if (availableTrains.Count == 0)
{
Console.WriteLine($"No trains found with {numberOfTickets} or more available seats for the given origin and destination.");
return;
}
Console.WriteLine($"\nTrains with {numberOfTickets} or more Available Seats:");
Console.WriteLine("---------------------------------------------------------------------------------------------------");
Console.WriteLine("Train Number | Train Name | Departure Time | Arrival Time | Origin | Destination | Available Seats");
Console.WriteLine("---------------------------------------------------------------------------------------------------");
foreach (Train train in availableTrains)
{
List<Booking> existingBookings = BookingRepository.GetBookingsByTrainNumberAndDate(train.TrainNumber, DateTime.Now); // Consider bookings for today
int bookedSeats = existingBookings.Sum(b => b.SeatNumbers.Count);
int availableSeats = train.TotalSeats - bookedSeats;
Console.WriteLine($"{train.TrainNumber,-13} | {train.TrainName,-16} | {train.DepartureTime,-24:f} | {train.ArrivalTime,-24:f} | {train.Origin,-10} | {train.Destination,-12} | {availableSeats,-15}");
}
Console.WriteLine("---------------------------------------------------------------------------------------------------");
}
// Method to dynamically allocate seats (US_PROG_007)
private static void DynamicallyAllocateSeats(Train train, DateTime bookingDate, int numberOfPassengers)
{
if (train == null)
{
Console.WriteLine("Train not found.");
return;
}
if (numberOfPassengers <= 0 || numberOfPassengers > 10)
{
Console.WriteLine("Number of passengers must be between 1 and 10.");
return;
}
if (bookingDate.Date < DateTime.Now.Date)
{
Console.WriteLine("Booking date cannot be in the past.");
return;
}
// Get existing bookings for the train and date to determine occupied seats
List<Booking> existingBookings = BookingRepository.GetBookingsByTrainNumberAndDate(train.TrainNumber, bookingDate);
List<int> occupiedSeats = new List<int>();
foreach (var booking in existingBookings)
{
occupiedSeats.AddRange(booking.SeatNumbers);
}
// Get all available seat numbers
List<int> allSeats = Enumerable.Range(1, train.TotalSeats).ToList();
List<int> availableSeats = allSeats.Except(occupiedSeats).ToList();
if (availableSeats.Count < numberOfPassengers)
{
Console.WriteLine("Not enough available seats to accommodate the requested number of passengers.");
return;
}
List<int> allocatedSeats = new List<int>();
// 1. Try to find adjacent seats
for (int i = 0; i <= availableSeats.Count - numberOfPassengers; i++)
{
bool areAdjacent = true;
for (int j = 0; j < numberOfPassengers; j++)
{
if (availableSeats[i + j] != availableSeats[i] + j)
{
areAdjacent = false;
break;
}
}
if (areAdjacent)
{
allocatedSeats = availableSeats.GetRange(i, numberOfPassengers);
break;
}
}
// 2. If adjacent seats not found, allocate closest available seats
if (allocatedSeats.Count == 0)
{
availableSeats.Sort(); // Sort for closest
allocatedSeats = availableSeats.Take(numberOfPassengers).ToList();
}
if (allocatedSeats.Count != numberOfPassengers)
{
Console.WriteLine("Error: Could not allocate the required number of seats.");
return; // Or throw an exception
}
// Display the allocated seats to the user for confirmation
Console.WriteLine("\nDynamically Allocated Seats:");
Console.WriteLine(string.Join(", ", allocatedSeats));
Console.Write("Do you want to confirm these seats? (yes/no): ");
string confirmation = Console.ReadLine().ToLower();
if (confirmation == "yes")
{
// Create a new booking with the allocated seats
decimal fare = allocatedSeats.Count * 100;
Booking newBooking = new Booking
{
CustomerID = loggedInUser.UserID, // Use the logged-in user's ID
TrainNumber = train.TrainNumber,
BookingDate = bookingDate,
SeatNumbers = allocatedSeats,
Fare = fare, // Calculate fare
BookingStatus = "Booked"
};
BookingRepository.AddBooking(newBooking);
Console.WriteLine($"Booking confirmed. Your Booking ID is {newBooking.BookingID}.");
Console.WriteLine($"Total Fare: ${newBooking.Fare}");
}
else
{
Console.WriteLine("Seat allocation cancelled.");
}
}
}
}