private string ValidateAvailableSeats(PurchaseTicketViewModel ticket, AvailableTrainViewModel train)
        {
            if ("business".Equals(ticket.TravellerClass))
            {
                int difference = (train.BusinessClassPassengersCount + ticket.PassengersCount)
                                 - AppConstants.TRAIN_CAPACITY_BUSINESS;

                if (difference > 0)
                {
                    int availableSeats = AppConstants.TRAIN_CAPACITY_BUSINESS - train.BusinessClassPassengersCount;
                    return(availableSeats > 0 ? $"There are only { availableSeats } seats available." : "There are no seats available");
                }
            }

            if ("economic".Equals(ticket.TravellerClass))
            {
                int difference = (train.EconomicClassPassengersCount + ticket.PassengersCount)
                                 - AppConstants.TRAIN_CAPACITY_ECONOMIC;

                if (difference > 0)
                {
                    int availableSeats = AppConstants.TRAIN_CAPACITY_ECONOMIC - train.EconomicClassPassengersCount;
                    return(availableSeats > 0 ? $"There are only { availableSeats } seats available." : "There are no seats available");
                }
            }

            return(string.Empty);
        }
        public ActionResult Purchase(PurchaseTicketViewModel ticket)
        {
            try
            {
                // TODO: Add insert logic here
                var currentUserId = User.Identity.GetUserId();
                var bus           = context.BusVehicles
                                    .Where(b => b.Id == ticket.Id)
                                    .SingleOrDefault();

                if (bus == null)
                {
                    return(new HttpStatusCodeResult(404));
                }

                var viewModel = new AvailableBusViewModel()
                {
                    Id            = bus.Id,
                    Capacity      = bus.Capacity,
                    Class         = bus.Class,
                    Route         = bus.Route,
                    Fare          = bus.Fare,
                    DepartureTime = bus.DepartureTime,
                };

                if (bus.DepartureTime < DateTime.Now)
                {
                    ViewBag.Error = "This bus has already departed.";
                    return(View(viewModel));
                }
                else if (bus.DepartureTime > DateTime.Now.AddDays(AppConstants.MAX_DAYS_BEFORE_RESERVATION))
                {
                    ViewBag.Error = "You can only purchase tickets as late as two weeks before departure.";
                    return(View(viewModel));
                }

                Reservation reservation = new Reservation()
                {
                    TotalSeat   = ticket.PassengersCount,
                    PurchasedOn = DateTime.Now,
                    PassengerID = context.Passengers
                                  .Where(u => u.UserID == currentUserId)
                                  .Select(p => p.Id)
                                  .SingleOrDefault(),
                    BusID       = bus.Id,
                    TotalAmount = ticket.PassengersCount * bus.Fare,
                    IsConfirmed = false
                };

                context.Reservations.InsertOnSubmit(reservation);
                context.SubmitChanges();

                return(RedirectToAction("List"));
            }
            catch
            {
                return(View());
            }
        }
        public ActionResult Purchase(PurchaseTicketViewModel ticket)
        {
            var currentUserId = User.Identity.GetUserId();
            var train         = db.Trains.Find(ticket.Id);

            if (train == null)
            {
                return(new HttpStatusCodeResult(404));
            }

            var viewModel = new AvailableTrainViewModel()
            {
                Id    = train.Id,
                Route = train.Route,
                BusinessClassPassengersCount = (db.TrainTickets
                                                .Where(t => t.TrainId == train.Id)
                                                .Where(t => t.IsConfirmed)
                                                .Where(t => t.IsBusinessClass)
                                                .Select(t => t.PassengersCount)
                                                .DefaultIfEmpty()
                                                .Sum()),
                EconomicClassPassengersCount = (db.TrainTickets
                                                .Where(t => t.TrainId == train.Id)
                                                .Where(t => t.IsConfirmed)
                                                .Where(t => !t.IsBusinessClass)
                                                .Select(t => t.PassengersCount)
                                                .DefaultIfEmpty()
                                                .Sum()),
                DepartureTime = train.DepartureTime
            };

            if (train.DepartureTime < DateTime.Now)
            {
                ViewBag.Error = "This train has already departed.";
                return(View(viewModel));
            }
            else if (train.DepartureTime > DateTime.Now.AddDays(AppConstants.MAX_DAYS_BEFORE_RESERVATION))
            {
                ViewBag.Error = "You can only purchase tickets as late as two weeks before departure.";
                return(View(viewModel));
            }

            string errorMessage = ValidateAvailableSeats(ticket, viewModel);

            if (!string.IsNullOrEmpty(errorMessage))
            {
                ViewBag.Error = errorMessage;
                return(View(viewModel));
            }

            var generatedTicket = new TrainTicket()
            {
                UserId          = new Guid(currentUserId),
                TrainId         = train.Id,
                Departure       = train.Route.Departure,
                Arrival         = train.Route.Arrival,
                DepartureTime   = train.DepartureTime,
                PurchasedOn     = DateTime.Now,
                IsBusinessClass = ticket.TravellerClass == "business" ? true : false,
                PassengersCount = ticket.PassengersCount,
                Price           = train.Route.Price * ticket.PassengersCount,
                IsConfirmed     = false
            };

            generatedTicket.Price *= generatedTicket.IsBusinessClass
                ? AppConstants.BUSINESS_CLASS_MULTIPLIER : 1.0m;

            db.TrainTickets.Add(generatedTicket);
            db.SaveChanges();

            return(SendPurchaseConfirmationEmail(generatedTicket.Id));
        }