public async Task CreateUser(AecUser user)
        {
            IdentityResult result = await _userManager.CreateAsync(new AecUser { UserName = user.UserName }, user.Password);

            if (!result.Succeeded)
            {
                string message = string.Join(Environment.NewLine, result.Errors);
                throw new InvalidOperationException(message);
            }
        }
        public async Task <BookingResult> CreateAsync(Cruise cruise, BookingSource source, bool allowCreateIfLocked = false)
        {
            if (cruise.IsLocked && !allowCreateIfLocked)
            {
                throw new BookingException("Cruise is locked, may not create bookings.");
            }

            BookingSource.Validate(source);
            var booking = Booking.FromSource(source, cruise.Id, _credentialsGenerator.GenerateBookingReference());

            /*
             * Start a low-isolation transaction just to give us rollback capability in case something fails in the middle of
             * the booking. Then acquire a lock (which is automagically tied to the transaction scope) to prevent multiple bookings
             * being written at once and potentially overcommitting our available cabins.
             */
            var tranOptions = new TransactionOptions {
                IsolationLevel = IsolationLevel.ReadUncommitted
            };

            using (var tran = new TransactionScope(TransactionScopeOption.Required, tranOptions, TransactionScopeAsyncFlowOption.Enabled))
                using (var db = DbUtil.Open())
                {
                    var cabinTypes = await _cabinRepository.GetActiveAsync(db, cruise);

                    var productTypes = await _productRepository.GetActiveAsync(db, cruise);

                    CheckCabinTypesValidity(booking.SubCruise, source.Cabins, cabinTypes);

                    await db.GetAppLockAsync(LockResource, LockTimeout);
                    await CheckCabinsAvailability(db, cruise, source.Cabins, cabinTypes);
                    await CheckProductsAvailability(db, cruise, source.Products);
                    await CreateBooking(db, booking);
                    await CreateCabins(db, booking, source.Cabins);
                    await CreateProducts(db, booking, source.Products);

                    decimal totalPrice = _priceCalculator.CalculatePrice(source.Cabins, source.Products, booking.Discount, cabinTypes, productTypes);
                    await db.ExecuteAsync("update [Booking] set [TotalPrice] = @TotalPrice where [Id] = @Id", new { TotalPrice = totalPrice, Id = booking.Id });

                    tran.Complete();
                }

            var password = _credentialsGenerator.GeneratePinCode();
            await _userManager.CreateAsync(new AecUser { UserName = booking.Reference, IsBooking = true }, password);

            return(new BookingResult {
                Reference = booking.Reference, Password = password
            });
        }