public async Task <IActionResult> Add(CartLine model) { try { if (ModelState.IsValid) { if (!model.AdultTicket.HasValue) { model.AdultTicket = 0; } if (!model.KidTicket.HasValue) { model.KidTicket = 0; } if (model.AdultTicket == 0 && model.KidTicket == 0) // if number of tickets = 0 { ModelState.AddModelError("", "You must choose at least 1 ticket for adult or kid"); } else { bool isAvailableTour = false; if (!string.IsNullOrWhiteSpace(model.Tour.Id)) { isAvailableTour = await tourDAL.IsAvailableTourAsync(model.Tour.Id); } if (!isAvailableTour) { ModelState.AddModelError("", "Tour " + model.Tour.Id.ToUpper() + " is not existed or available"); return(RedirectToAction(nameof(Index))); //if tour is not available then report error at cart view since tour details can be found } else { int takenSlot = await tourDAL.GetTakenSlotByTourIdAsync(model.Tour.Id); int maxGuest = await tourDAL.GetMaxGuestByTourIdAsync(model.Tour.Id); CartLine line = cart.Lines.FirstOrDefault(x => x.Tour.Id == model.Tour.Id); // find if tour is in cart int totalTicket = (line?.AdultTicket ?? 0) + (line?.KidTicket ?? 0); if ((totalTicket + model.AdultTicket + model.KidTicket) > (maxGuest - takenSlot)) { ModelState.AddModelError("", "Not enough tickets. You've already got " + totalTicket + " of this item"); } else { cart.AddItem(model); return(RedirectToAction(nameof(Index))); } } } } return(RedirectToAction("Details", "Tour", new { model.Tour.Id })); //report error at tour details if model properties is invalid or not enough tickets } catch (Exception ex) { logger.Error(ex.Message); throw; } }