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)); } }
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)); }
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}."); } }
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)); }
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 }); }