public int GetAllocatedHours(string start, string end)
        {
            DateTime startDate = Convert.ToDateTime(start);
            DateTime endDate   = Convert.ToDateTime(end);

            return(AllocatedHoursCalculator.CalculateAllocatedHours(startDate, endDate));
        }
        //[Authorize(Policy = "RequireLogin", AuthenticationSchemes = OAuthValidationDefaults.AuthenticationScheme)]
        public async Task <IActionResult> PostBooking([FromBody] BookingViewModel bookingModel)
        {
            if (!ModelState.IsValid)
            {
                return(BadRequest(ModelState));
            }

            var errors = BookingRules(bookingModel).Result;

            if (!string.IsNullOrEmpty(errors))
            {
                return(BadRequest(errors));
            }

            var allocatedHours = AllocatedHoursCalculator.CalculateAllocatedHours(bookingModel.StartDateTime, bookingModel.EndDateTime);

            var booking = new Booking
            {
                BoatId         = bookingModel.BoatId,
                StartDateTime  = bookingModel.StartDateTime,
                EndDateTime    = bookingModel.EndDateTime,
                NonMemberCrews = bookingModel.NonMemberCrews,
                Itinerary      = bookingModel.NonMemberCrews,
                AllocatedHours = allocatedHours,
                UserId         = bookingModel.UserId
            };

            booking.UserBookings = new List <UserBooking>();

            foreach (var member in bookingModel.MemberCrews)
            {
                var user = await _userManager.FindByIdAsync(member.UserId);

                user.CreditBalance -= member.UsedCredit;

                _context.Entry(user).State = EntityState.Modified;

                await _context.SaveChangesAsync();

                var BookingToAdd = new UserBooking
                {
                    BookingId  = booking.BookingId,
                    UserId     = member.UserId,
                    UsedCredit = member.UsedCredit
                };

                booking.UserBookings.Add(BookingToAdd);
            }

            _context.Bookings.Add(booking);
            await _context.SaveChangesAsync();

            return(Ok(bookingModel));
        }
        private async Task <string> BookingRules(BookingViewModel bookingModel)
        {
            // crew requirements
            bool daySkipper    = false;
            bool cruiseSkipper = false;
            int  totalCredit   = 0;

            var bookings = _context.Bookings.Where(b => b.BoatId == bookingModel.BoatId);

            foreach (var b in bookings)
            {
                if (bookingModel.StartDateTime < b.EndDateTime && b.StartDateTime < bookingModel.EndDateTime)
                {
                    return("Overlap booking with " + bookingModel.BoatName);
                }
            }

            var user = await _userManager.FindByIdAsync(bookingModel.UserId);

            if (user == null)
            {
                return("User not found");
            }

            if (!await _userManager.IsInRoleAsync(user, Role.MemberGoodStanding))
            {
                return("This user cannot make booking");
            }

            if (bookingModel.EndDateTime.Subtract(bookingModel.StartDateTime).Duration().TotalHours > 72 ||
                bookingModel.EndDateTime.Subtract(bookingModel.StartDateTime).Duration().TotalHours <= 0)
            {
                return("Booking only allows less than 72 hours");
            }

            if (bookingModel.MemberCrews == null)
            {
                return("No member crew is selected");
            }

            foreach (var m in bookingModel.MemberCrews)
            {
                var member = await _userManager.FindByIdAsync(m.UserId);

                if (member.CreditBalance < m.UsedCredit)
                {
                    return(member.FirstName + " " + member.LastName + " has no enough credits");
                }

                totalCredit += m.UsedCredit;

                if (_userManager.IsInRoleAsync(member, Role.CruiseSkipper).Result)
                {
                    cruiseSkipper = true;
                }

                if (_userManager.IsInRoleAsync(member, Role.DaySkipper).Result)
                {
                    daySkipper = true;
                }
            }

            var days = bookingModel.EndDateTime.Subtract(bookingModel.StartDateTime).Duration().TotalDays;

            if (days >= 1 && !cruiseSkipper)
            {
                return("Requires Cruise Skipper");
            }
            else
            {
                if (days < 1 && !(daySkipper || cruiseSkipper))
                {
                    return("Requires Day Skippers");
                }
            }

            var boat = await _context.Boats.SingleOrDefaultAsync(b => b.BoatId == bookingModel.BoatId);

            if (boat == null)
            {
                return("Boat Not Found");
            }

            var allocatedHours = AllocatedHoursCalculator.CalculateAllocatedHours(bookingModel.StartDateTime, bookingModel.EndDateTime);

            if (totalCredit != allocatedHours * boat.CreditsPerHourOfUsage)
            {
                return("Total Credit doesnt match " + allocatedHours);
            }

            return(string.Empty);
        }