public async Task <BookingResponse> GetBookingsWeek(BookingsWeekRequest model)
        {
            // Get activity and check if it exists
            var activity = await _bookingDbContext.Activities.Include(a => a.Bookings)
                           .Where(a => a.Id == model.ActivityId).FirstAsync();

            if (activity == null)
            {
                return(new BookingResponse(400, "Activity does not exist"));
            }

            var date = DateTime.Now;

            // Check if year is in the before or more than 1 year after current year
            if (model.Year < date.Year || model.Year > date.Year + 1)
            {
                return(new BookingResponse(400, "Year must be current or next year"));
            }

            // Check if week is before current week
            if (model.Year == date.Year && model.Week < ISOWeek.GetWeekOfYear(date))
            {
                return(new BookingResponse(400, "Week must be in the future"));
            }

            // Check if week is less than 1
            if (model.Week < 1)
            {
                return(new BookingResponse(400, "Week must be at least 1"));
            }
            var numberOfWeeks = ISOWeek.GetWeeksInYear(model.Year);

            // Check if week is more than number of weeks in given year
            if (model.Week > numberOfWeeks)
            {
                return(new BookingResponse(400, "Week must be at most " + numberOfWeeks));
            }

            // Calculate from and to dates for use in query
            var centralEuropean = TimeZoneInfo.FindSystemTimeZoneById("Central European Standard Time");
            var now             = TimeZoneInfo.ConvertTime(DateTime.Now, centralEuropean);
            var startOfWeek     = ISOWeek.ToDateTime(model.Year, model.Week, DayOfWeek.Monday);
            var from            = now > startOfWeek ? now : startOfWeek;
            var nextWeek        = model.Week == numberOfWeeks ? 1 : model.Week + 1;
            var newYear         = model.Week == numberOfWeeks ? model.Year + 1 : model.Year;
            var to = ISOWeek.ToDateTime(newYear, nextWeek, DayOfWeek.Monday);

            // Get bookings in given week from now
            var bookings = activity.Bookings.Where(b => b.Start >= from && b.Start < to);

            var openHours = activity.Close - activity.Open;
            var times     = new int[7][];

            // Generate array with all bookings in a week
            for (var i = 0; i < 7; i++)
            {
                times[i] = new int[openHours];
                for (var j = 0; j < openHours; j++)
                {
                    var dateTime = startOfWeek.AddDays(i).AddHours(activity.Open + j);
                    if (now > dateTime)
                    {
                        times[i][j] = 2;
                    }
                }
            }

            // Go through bookings and set times as booked
            foreach (var booking in bookings)
            {
                var current = booking.Start;
                while (current < booking.End)
                {
                    var day  = GetDayOfWeek(current.DayOfWeek);
                    var hour = current.Hour - activity.Open;
                    if (times[day][hour] != 2)
                    {
                        times[day][hour] = 1;
                    }

                    current = current.AddHours(1);
                }
            }


            return(new BookingResponse(times));
        }
예제 #2
0
        public async Task <IActionResult> GetBookingsWeek([FromQuery] BookingsWeekRequest model)
        {
            var response = await _bookingService.GetBookingsWeek(model);

            return(StatusCode(response.StatusCode, response));
        }