public IActionResult BookTicket(int id, TimeSpan departureTime, DateTime date, string companyId)
        {
            var departureDateTime = new DateTime(date.Year, date.Month, date.Day, departureTime.Hours, departureTime.Minutes, departureTime.Seconds);

            if (!this.routes.RouteExists(id, departureTime) || departureDateTime < DateTime.UtcNow.ToLocalTime())
            {
                this.GenerateAlertMessage(WebConstants.Message.InvalidRoute, Alert.Danger);
                return(this.RedirectToHome());
            }

            var form = new BookTicketFormModel();

            var routeTicketBookingInfo = this.routes.GetRouteTicketBookingInfo(id, departureDateTime);

            this.GenerateBusSchemaSeats(form, routeTicketBookingInfo);

            form.BusSeats          = (int)routeTicketBookingInfo.BusType;
            form.DepartureDateTime = departureDateTime;
            form.Duration          = routeTicketBookingInfo.Duration;
            form.RouteId           = id;
            form.StartTownId       = routeTicketBookingInfo.StartTownId;
            form.EndTownId         = routeTicketBookingInfo.EndTownId;
            form.CompanyName       = routeTicketBookingInfo.CompanyName;
            form.CompanyId         = companyId;
            form.StartStation      = routeTicketBookingInfo.StartStation;
            form.EndStation        = routeTicketBookingInfo.EndStation;

            return(View(form));
        }
 private void GenerateBusSchemaSeats(BookTicketFormModel form, RouteBookTicketInfoServiceModel info)
 {
     for (int i = 1; i <= (int)info.BusType; i++)
     {
         form.Seats.Add(new BusSeat()
         {
             Value    = i,
             Checked  = false,
             Text     = i.ToString(),
             Disabled = info.ReservedTickets.Any(n => n == i)
         });
     }
 }
        public IActionResult BookTicket(BookTicketFormModel form)
        {
            if (!ModelState.IsValid)
            {
                ModelState.AddModelError(string.Empty, WebConstants.Message.NoneSelectedSeats);
                this.GenerateBusSchemaSeats(form, this.routes.GetRouteTicketBookingInfo(form.RouteId, form.DepartureDateTime));
                return(View(form));
            }

            if (!this.routes.RouteExists(form.RouteId, form.DepartureDateTime.TimeOfDay) || form.DepartureDateTime < DateTime.UtcNow.ToLocalTime())
            {
                this.GenerateAlertMessage(WebConstants.Message.InvalidRoute, Alert.Danger);
                return(this.RedirectToHome());
            }

            var alreadyReservedTickets = this.tickets.GetAlreadyReservedTickets(form.RouteId, form.DepartureDateTime);

            if (alreadyReservedTickets.Count() == form.BusSeats)
            {
                this.GenerateAlertMessage(string.Format(WebConstants.Message.RouteSoldOut, form.StartStation, form.EndStation, form.DepartureDateTime.Date.ToYearMonthDayFormat(), form.DepartureDateTime.TimeOfDay), Alert.Warning);

                return(RedirectToAction(nameof(Search), new { startTown = form.StartTownId, endTown = form.EndTownId, date = form.DepartureDateTime.Date, companyId = form.CompanyId }));
            }

            var reservedTickets = form.Seats
                                  .Where(s => s.Checked && !s.Disabled)
                                  .Select(s => s.Value)
                                  .ToList();

            var matchingSeats = reservedTickets.Intersect(alreadyReservedTickets).ToList();

            if (matchingSeats.Count > 0)
            {
                ModelState.AddModelError(string.Empty, string.Format(WebConstants.Message.SeatsAlreadyTaken, string.Join(", ", matchingSeats)));
                return(View(form));
            }

            var success = this.tickets.Add(form.RouteId, form.DepartureDateTime, reservedTickets, this.userManager.GetUserId(User));

            if (!success)
            {
                this.GenerateAlertMessage(WebConstants.Message.InvalidRoute, Alert.Danger);
                return(this.RedirectToHome());
            }

            this.GenerateAlertMessage(string.Format(WebConstants.Message.SuccessfullyTicketReservation, string.Join(", ", reservedTickets), form.StartStation, form.EndStation, form.DepartureDateTime), Alert.Success);

            return(RedirectToHome());
        }