예제 #1
0
        public async Task <IHttpActionResult> Current(string subCruise)
        {
            var cruise = await _cruiseRepository.GetActiveAsync();

            if (null == cruise)
            {
                return(NotFound());
            }

            var subCruiseCode = SubCruiseCode.FromString(subCruise ?? string.Empty);

            using (var db = DbUtil.Open())
            {
                return(this.OkCacheControl(new
                {
                    AgeDistribution = await _reportingService.GetAgeDistribution(db, cruise, subCruiseCode),
                    // Bookings per subcruise is not supported, so we null this one if a subcruise is provided
                    BookingsByPayment = SubCruiseCode.None != subCruiseCode ? null : await _reportingService.GetNumberOfBookingsByPaymentStatus(db, cruise),
                    Genders = await _reportingService.GetGenders(db, cruise, subCruiseCode),
                    TopContacts = await _reportingService.GetTopContacts(db, cruise, subCruiseCode, 15),
                    TopGroups = await _reportingService.GetTopGroups(db, cruise, subCruiseCode, 15)
                },
                                           WebConfig.DynamicDataMaxAge));
            }
        }
예제 #2
0
        public async Task <IHttpActionResult> Summary(string subCruise)
        {
            var cruise = await _cruiseRepository.GetActiveAsync();

            if (null == cruise)
            {
                return(NotFound());
            }

            var subCruiseCode = SubCruiseCode.FromString(subCruise ?? string.Empty);

            Report[] reports = await _reportRepository.GetActiveAsync(cruise, subCruiseCode);

            return(this.OkCacheControl(ReportSummary.FromReports(reports), WebConfig.DynamicDataMaxAge));
        }
예제 #3
0
        void CheckCabinTypesValidity(SubCruiseCode subCruiseForBooking, List <BookingSource.Cabin> sourceCabins, CruiseCabinWithType[] cabinTypes)
        {
            var typeDict = cabinTypes.ToDictionary(c => c.Id, c => c.SubCruise);

            if (sourceCabins.Any(cabin => !typeDict.ContainsKey(cabin.TypeId) || !subCruiseForBooking.Equals(SubCruiseCode.FromString(typeDict[cabin.TypeId]))))
            {
                throw new BookingException($"One or more cabin types in the booking are not valid for sub-cruise {subCruiseForBooking}.");
            }
        }
예제 #4
0
        public async Task <IHttpActionResult> Excel(bool onlyFullyPaid = false, string updatedSince = null, string subCruise = null)
        {
            var activeCruise = await _cruiseRepository.GetActiveAsync();

            if (null == activeCruise)
            {
                return(NotFound());
            }

            SubCruiseCode subCruiseCode    = string.IsNullOrEmpty(subCruise) ? SubCruiseCode.First : SubCruiseCode.FromString(subCruise);
            DateTime?     updatedSinceDate = string.IsNullOrEmpty(updatedSince)
                                ? null
                                : new DateTime?(DateTime.ParseExact(updatedSince, UpdatedSinceFormat, CultureInfo.InvariantCulture));

            var      exportToExcelGenerator = new ExportToExcelGenerator(_cabinRepository, _productRepository);
            Workbook workbook = await exportToExcelGenerator.ExportToWorkbookAsync(activeCruise, onlyFullyPaid, subCruiseCode.ToString(), updatedSinceDate);

            return(CreateHttpResponseMessage(workbook, subCruise));
        }
예제 #5
0
        public async Task <BookingResult> UpdateAsync(Cruise cruise, BookingSource source, bool allowUpdateDetails = false, bool allowUpdateIfLocked = false)
        {
            BookingSource.ValidateCabins(source);
            if (allowUpdateDetails)
            {
                source.ValidateDetails();
            }

            Booking booking;

            // See CreateAsync regarding the use of transaction + applock here.
            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(SubCruiseCode.FromString(source.SubCruise), source.Cabins, cabinTypes);

                    await db.GetAppLockAsync(LockResource, LockTimeout);

                    booking = await FindByReferenceAsync(db, source.Reference);

                    if (null == booking || booking.CruiseId != cruise.Id)
                    {
                        throw new BookingException($"Booking with reference {source.Reference} not found or not in active cruise.");
                    }
                    if ((cruise.IsLocked || booking.IsLocked) && !allowUpdateIfLocked)
                    {
                        throw new BookingException($"Booking with reference {source.Reference} is locked, may not update.");
                    }

                    // Get the booking contents before deleting it so we can detect changes
                    BookingCabinWithPax[] originalCabins = await GetCabinsForBooking(db, booking.Id);

                    await DeleteCabins(db, booking);
                    await CheckCabinsAvailability(db, cruise, source.Cabins, cabinTypes);
                    await CreateCabins(db, booking, source.Cabins);

                    await DeleteProducts(db, booking);
                    await CheckProductsAvailability(db, cruise, source.Products);
                    await CreateProducts(db, booking, source.Products);

                    await CreateChanges(db, booking, originalCabins, source.Cabins);

                    decimal totalPrice = _priceCalculator.CalculatePrice(source.Cabins, source.Products, booking.Discount, cabinTypes, productTypes);
                    if (allowUpdateDetails)
                    {
                        await db.ExecuteAsync(
                            "update [Booking] set [FirstName] = @FirstName, [LastName] = @LastName, [Email] = @Email, [PhoneNo] = @PhoneNo, [Lunch] = @Lunch, [InternalNotes] = @InternalNotes, [SubCruise] = @SubCruise, [TotalPrice] = @TotalPrice, [Updated] = sysdatetime() where [Id] = @Id",
                            new
                        {
                            FirstName  = source.FirstName, LastName = source.LastName, Email = source.Email, PhoneNo = source.PhoneNo, Lunch = source.Lunch, InternalNotes = source.InternalNotes, SubCruise = source.SubCruise,
                            TotalPrice = totalPrice, Id = booking.Id
                        });
                    }
                    else
                    {
                        await db.ExecuteAsync("update [Booking] set [SubCruise] = @SubCruise, [TotalPrice] = @TotalPrice, [Updated] = sysdatetime() where [Id] = @Id",
                                              new { SubCruise = source.SubCruise, TotalPrice = totalPrice, Id = booking.Id });
                    }

                    tran.Complete();
                }

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