public async Task ExecuteAsync(BookingRequestCommand command, IExecutionContext executionContext) { using (var scope = DomainRepository.Transactions().CreateScope()) { var tenantCategory = await TenantCategoryProvider.GetTenantCategoryById(command.TenantCategoryId.Value); DateTime lastAllowedArrivalDate = DateTime.Now.AddMonths(tenantCategory.AllowedBookingFutureMonths); if (command.ArrivalDate.Value >= lastAllowedArrivalDate || command.DepartureDate.Value >= lastAllowedArrivalDate) { throw new ValidationErrorException(new ValidationError($"Den valgte lejertype kan ikke reservere mere end {tenantCategory.AllowedBookingFutureMonths} måneder ud i fremtiden. Dvs. senest {lastAllowedArrivalDate.ToShortDateString()}.", nameof(command.ArrivalDate))); } int bookingNumber = await SequenceNumberGenerator.NextNumber("BookingNumber"); var booking = new BookingDataModel { BookingNumber = bookingNumber, ArrivalDate = command.ArrivalDate.Value, DepartureDate = command.DepartureDate.Value, OnlySelectedWeekdays = command.OnlySelectedWeekdays, SelectedWeekdays = command.SelectedWeekdays, TenantCategoryId = command.TenantCategoryId.Value, TenantName = command.TenantName, Purpose = command.Purpose, ContactName = command.ContactName, ContactPhone = command.ContactPhone, ContactAddress = command.ContactAddress, ContactCity = command.ContactCity, ContactEMail = command.ContactEMail, Comments = command.Comments, RentalPrice = null, // To be set later Deposit = BookingSettings.StandardDeposit, BookingState = BookingDataModel.BookingStateType.Requested }; await booking.AddLogEntry(CurrentUserProvider, "Reservationen blev indsendt af lejer."); await SendConfirmationMail(booking); await SendNotificationMail(booking); var addCommand = new AddCustomEntityCommand { CustomEntityDefinitionCode = BookingCustomEntityDefinition.DefinitionCode, Model = booking, Title = booking.MakeTitle(), Publish = true, }; await DomainRepository.WithElevatedPermissions().CustomEntities().AddAsync(addCommand); await scope.CompleteAsync(); } }
public async Task ExecuteAsync(CheckoutBookingCommand command, IExecutionContext executionContext) { using (var scope = DomainRepository.Transactions().CreateScope()) { BookingDataModel booking = await BookingProvider.GetBookingById(command.Id); if (command.Token != booking.TenantSelfServiceToken) { throw new AuthenticationFailedException("Ugyldigt eller manglende adgangsnøgle"); } if (booking.BookingState == BookingDataModel.BookingStateType.Requested) { throw new ValidationErrorException("Det er ikke muligt at indberette slutafregning, da reservationen endnu ikke er godkendt."); } else if (booking.BookingState == BookingDataModel.BookingStateType.Closed) { throw new ValidationErrorException("Det er ikke muligt at indberette slutafregning, da reservationen allerede er afsluttet."); } booking.IsCheckedOut = true; booking.ElectricityReadingStart = command.StartReading; booking.ElectricityReadingEnd = command.EndReading; booking.ElectricityPriceUnit = BookingSettings.ElectricityPrice; if (!string.IsNullOrEmpty(command.Comments)) { booking.Comments += $"\n\n=== Kommentarer til slutregnskab [{DateTime.Now}] ===\n{command.Comments}"; } await booking.AddLogEntry(CurrentUserProvider, "Elforbrug blev indmeldt af lejer."); // Do not use BookingSummary for mails as it will be the old version of the booking, from before readings were updated. // Also make sure mails are sent before updating the entity, as sent mail will be refered by the model. await SendCheckoutConfirmationMail(booking); await SendAdminNotificationMail(booking); UpdateCustomEntityDraftVersionCommand updateCmd = new UpdateCustomEntityDraftVersionCommand { CustomEntityDefinitionCode = BookingCustomEntityDefinition.DefinitionCode, CustomEntityId = command.Id, Title = booking.MakeTitle(), Publish = true, Model = booking }; await DomainRepository.WithElevatedPermissions().CustomEntities().Versions().UpdateDraftAsync(updateCmd); await scope.CompleteAsync(); } }
public async Task ExecuteAsync(SendBookingMailCommand command, IExecutionContext executionContext) { PermissionValidationService.EnforceCustomEntityPermission <CustomEntityUpdatePermission>(BookingCustomEntityDefinition.DefinitionCode, executionContext.UserContext); using (var scope = DomainRepository.Transactions().CreateScope()) { BookingDataModel booking = await BookingProvider.GetBookingById(command.BookingId); await booking.AddLogEntry(CurrentUserProvider, $"Sendt: {command.Subject}."); byte[] mailBody = System.Text.Encoding.UTF8.GetBytes(command.Message); var addDcoumentCommand = new AddDocumentCommand { Title = command.Subject, MimeType = "text/html", Body = mailBody }; await CommandExecutor.ExecuteAsync(addDcoumentCommand); booking.AddDocument(command.Subject, addDcoumentCommand.OutputDocumentId); UpdateCustomEntityDraftVersionCommand updateCmd = new UpdateCustomEntityDraftVersionCommand { CustomEntityDefinitionCode = BookingCustomEntityDefinition.DefinitionCode, CustomEntityId = command.BookingId, Title = booking.MakeTitle(), Publish = true, Model = booking }; await DomainRepository.CustomEntities().Versions().UpdateDraftAsync(updateCmd); MailAddress to = new MailAddress(booking.ContactEMail, booking.ContactName); MailMessage message = new MailMessage { To = to, Subject = command.Subject, HtmlBody = command.Message }; // It is not really a good idea to contact a mail server during a transaction, but ... // 1) I really don't want the mail being registered in the database as "sent" if the mail sending fails. // 2) One can hope that the dispatcher simply adds the message to an outgoing mail queue. // (and, yes, sending mails may fail much later with an "unknown recipient" or similar) await MailDispatchService.DispatchAsync(message); await scope.CompleteAsync(); } }