public Showtime CreateShowtime(ShowtimeRequest showtimeRequest)
        {
            Showtime showtime = new Showtime();

            if (showtime.Status != null)
            {
                showtime.Status = showtimeRequest.Status;
            }
            else
            {
                showtime.Status = Constants.SHOWTIME_STATUS_ACTIVE;
            }
            showtime.StartAt = DateTime.Parse(showtimeRequest.StartAt);
            showtime.Movie   = dbContext.Movies.Where(m => m.Id == showtimeRequest.MovieId).FirstOrDefault();
            if (showtime.Movie != null)
            {
                showtime.EndAt = showtime.StartAt.AddMinutes(showtime.Movie.Runtime);
            }
            showtime.BasePrice  = showtimeRequest.BasePrice;
            showtime.Room       = dbContext.Rooms.Where(r => r.Id == showtimeRequest.RoomId).FirstOrDefault();
            showtime.ScreenType = dbContext.ScreenTypes.Where(st => st.Id == showtimeRequest.ScreenTypeId).FirstOrDefault();
            dbContext.Add(showtime);
            bool isSuccess = Save();

            if (!isSuccess)
            {
                return(null);
            }
            return(showtime);
        }
        public IActionResult Post([FromBody] ShowtimeRequest showtimeRequest)
        {
            if (showtimeRequest == null)
            {
                return(StatusCode(400, ModelState));
            }

            var statusCode = ValidateShowtime(showtimeRequest);


            if (!ModelState.IsValid)
            {
                return(StatusCode(statusCode.StatusCode));
            }

            var showtime = showtimeRepository.CreateShowtime(showtimeRequest);

            if (showtime == null)
            {
                var error = new Error()
                {
                    message = "Showtime went oopsie when creating"
                };
                return(StatusCode(400, error));
            }
            return(Ok(new ShowtimeDTO(showtime)));
        }
        public IActionResult Put(int id, [FromBody] ShowtimeRequest showtimeRequest)
        {
            if (showtimeRepository.GetShowtimeById(id) == null)
            {
                return(NotFound());
            }

            if (showtimeRequest == null)
            {
                return(StatusCode(400, ModelState));
            }

            var statusCode = ValidateShowtime(showtimeRequest);

            if (!ModelState.IsValid)
            {
                return(StatusCode(statusCode.StatusCode));
            }

            var showtime = showtimeRepository.UpdateShowtime(id, showtimeRequest);

            if (showtime == null)
            {
                var error = new Error()
                {
                    message = "Showtime went oopsie when updating"
                };
                return(StatusCode(400, error));
            }
            return(Ok(new ShowtimeDTO(showtime)));
        }
        public Showtime UpdateShowtime(int id, ShowtimeRequest showtimeRequest)
        {
            Showtime showtime = dbContext.Showtime.Where(s => s.Id == id).FirstOrDefault();

            showtime.Status  = showtimeRequest.Status;
            showtime.StartAt = DateTime.Parse(showtimeRequest.StartAt);
            showtime.Movie   = dbContext.Movies.Where(m => m.Id == showtimeRequest.MovieId).FirstOrDefault();
            if (showtime.Movie != null)
            {
                showtime.EndAt = showtime.StartAt.AddMinutes(showtime.Movie.Runtime);
            }
            showtime.BasePrice  = showtimeRequest.BasePrice;
            showtime.Room       = dbContext.Rooms.Where(r => r.Id == showtimeRequest.RoomId).FirstOrDefault();
            showtime.ScreenType = dbContext.ScreenTypes.Where(st => st.Id == showtimeRequest.ScreenTypeId).FirstOrDefault();
            dbContext.Update(showtime);
            bool isSuccess = Save();

            if (!isSuccess)
            {
                return(null);
            }
            return(showtime);
        }
        private StatusCodeResult ValidateShowtime(ShowtimeRequest showtimeRequest)
        {
            try
            {
                bool validFlag;

                // Check Status
                validFlag = showtimeRequest.Status == Constants.SHOWTIME_STATUS_ACTIVE ||
                            showtimeRequest.Status == Constants.SHOWTIME_STATUS_INACTIVE;
                if (!validFlag)
                {
                    ModelState.AddModelError("", $"Status not valid, can only be {Constants.SHOWTIME_STATUS_ACTIVE} "
                                             + $"or {Constants.SHOWTIME_STATUS_INACTIVE}");
                    return(StatusCode(400));
                }

                // Check RoomId, ScreenTypeId and MovieId valid
                var movieSupportedScreenTypeIds = screenTypeRepository
                                                  .GetScreenTypesByMovieId(showtimeRequest.MovieId)
                                                  .Select(screenTypeDTO => screenTypeDTO.Id).ToList();
                var roomSupportedScreenTypeIds = screenTypeRepository
                                                 .GetScreenTypesByRoomId(showtimeRequest.RoomId)
                                                 .Select(screenTypeDTO => screenTypeDTO.Id).ToList();
                validFlag = movieSupportedScreenTypeIds.Intersect(roomSupportedScreenTypeIds)
                            .Contains(showtimeRequest.ScreenTypeId);
                if (!validFlag)
                {
                    ModelState.AddModelError("", "Unsupported ScreenType for Room or Movie");
                    return(StatusCode(400));
                }

                // Check end at
                DateTime startAt    = DateTime.Parse(showtimeRequest.StartAt);
                Movie    movie      = movieRepository.GetMovieById(showtimeRequest.MovieId);
                DateTime endAt      = startAt.AddMinutes(movie.Runtime);
                DateTime movieEndAt = movie.EndAt;
                validFlag = DateTime.Compare(endAt, movieEndAt) <= 0;
                if (!validFlag)
                {
                    ModelState.AddModelError("", "Showtime breaks space time continuum");
                    return(StatusCode(400));
                }
                DateTime now = DateTime.Now;
                validFlag = DateTime.Compare(now, endAt) <= 0;
                if (!validFlag)
                {
                    ModelState.AddModelError("", "Need a time machine to see this movie");
                    return(StatusCode(400));
                }

                // Check showtime overlap
                var showtimes = showtimeRepository.GetShowtimesByRoomId(showtimeRequest.RoomId);
                foreach (ShowtimeDTO showtime in showtimes)
                {
                    validFlag = showtime.StartAt > endAt || showtime.EndAt < startAt;
                    if (!validFlag)
                    {
                        ModelState.AddModelError("", "Showtimes overlap");
                        return(StatusCode(400));
                    }
                }
            }
            catch (SystemException ex)
            {
                ModelState.AddModelError("", ex.Message);
                return(StatusCode(400));
            }

            return(NoContent());
        }