public async Task ExecuteAsync(AnonymizeBookingsCommand command, IExecutionContext executionContext) { PermissionValidationService.EnforceCustomEntityPermission <CustomEntityDeletePermission>(BookingCustomEntityDefinition.DefinitionCode, executionContext.UserContext); var query = new SearchBookingSummariesQuery { BookingState = new BookingDataModel.BookingStateType[] { BookingDataModel.BookingStateType.Closed }, Start = new DateTime(2000, 1, 1), End = DateTime.Now.AddYears(-3) }; command.AnonymizedCount = 0; foreach (KeyValuePair <int, BookingDataModel> bookingEntry in (await BookingProvider.FindBookingDataInInterval(query)).ToList()) { BookingDataModel booking = bookingEntry.Value; // Protected agains mistakes in the query by checking values again if (!booking.IsArchived && booking.BookingState == BookingDataModel.BookingStateType.Closed && booking.DepartureDate.Value.AddYears(3) < DateTime.Now) { booking.TenantName = "---"; booking.Purpose = "---"; booking.ContactName = "---"; booking.ContactEMail = "ukendt@ukendte-mailmodtagere"; booking.ContactPhone = "---"; booking.ContactAddress = "---"; booking.ContactCity = "---"; booking.Comments = "---"; foreach (var document in booking.Documents) { var deleteDocumentCommand = new DeleteDocumentCommand { Id = document.DocumentId }; await CommandExecutor.ExecuteAsync(deleteDocumentCommand); } booking.LogEntries.Clear(); booking.Documents.Clear(); booking.IsArchived = true; command.AnonymizedCount++; UpdateCustomEntityDraftVersionCommand updateCmd = new UpdateCustomEntityDraftVersionCommand { CustomEntityDefinitionCode = BookingCustomEntityDefinition.DefinitionCode, CustomEntityId = bookingEntry.Key, Title = booking.MakeTitle(), Publish = true, Model = booking }; await DomainRepository.CustomEntities().Versions().UpdateDraftAsync(updateCmd); } } }
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(UpdateBookingCommand command, IExecutionContext executionContext) { PermissionValidationService.EnforceCustomEntityPermission <CustomEntityUpdatePermission>(BookingCustomEntityDefinition.DefinitionCode, executionContext.UserContext); using (var scope = DomainRepository.Transactions().CreateScope()) { // Verify teneant category await TenantCategoryProvider.GetTenantCategoryById(command.TenantCategoryId.Value); BookingDataModel booking = await BookingProvider.GetBookingById(command.BookingId); booking.ArrivalDate = command.ArrivalDate.Value; booking.DepartureDate = command.DepartureDate.Value; booking.OnlySelectedWeekdays = command.OnlySelectedWeekdays; booking.SelectedWeekdays = command.SelectedWeekdays; booking.TenantCategoryId = command.TenantCategoryId; booking.TenantName = command.TenantName; booking.Purpose = command.Purpose; booking.ContactName = command.ContactName; booking.ContactPhone = command.ContactPhone; booking.ContactAddress = command.ContactAddress; booking.ContactCity = command.ContactCity; booking.ContactEMail = command.ContactEMail; booking.Comments = command.Comments; booking.RentalPrice = command.RentalPrice; booking.BookingState = command.BookingState; booking.IsApproved = command.IsApproved; booking.IsCancelled = command.IsCancelled; booking.IsCheckedOut = command.IsCheckedOut; booking.IsArchived = command.IsArchived; booking.WelcomeLetterIsSent = command.WelcomeLetterIsSent; booking.Deposit = command.Deposit; booking.DepositReceived = command.DepositReceived; booking.ElectricityReadingStart = command.ElectricityReadingStart; booking.ElectricityReadingEnd = command.ElectricityReadingEnd; booking.ElectricityPriceUnit = command.ElectricityPriceUnit; UpdateCustomEntityDraftVersionCommand updateCmd = new UpdateCustomEntityDraftVersionCommand { CustomEntityDefinitionCode = BookingCustomEntityDefinition.DefinitionCode, CustomEntityId = command.BookingId, Title = booking.MakeTitle(), Publish = true, Model = booking }; await DomainRepository.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(); } }
public async Task ExecuteAsync(ImportBookingsCommand command, IExecutionContext executionContext) { PermissionValidationService.EnforceCustomEntityPermission <CustomEntityUpdatePermission>(BookingCustomEntityDefinition.DefinitionCode, executionContext.UserContext); DataSet bookings = new DataSet(); bookings.ReadXml(command.ReadyToReadInput); var groupedBookings = bookings.Tables[0].Rows .Cast <DataRow>() .GroupBy(row => row["AftaleID"].ToString()); int count = 0; foreach (var bookingGroup in groupedBookings) { try { int bookingNumber = Convert.ToInt32(bookingGroup.Key); string startStr = bookingGroup.Min(b => b["Dato"].ToString()); DateTime arrivalDate = DateTime.SpecifyKind(DateTime.Parse(startStr), DateTimeKind.Utc); string endStr = bookingGroup.Max(b => b["Dato"].ToString()); DateTime departureDate = DateTime.SpecifyKind(DateTime.Parse(endStr), DateTimeKind.Utc); DataRow row = bookingGroup.First(); string status = row["Status"].ToString(); string origin1 = row["HvorDuFra"].ToString(); string origin2 = row["Fra"].ToString(); string purpose = row["Formaal"].ToString(); string contactName = row["KontaktPerson"].ToString(); string contactEmail = row["Email"].ToString(); string contactAddress = row["Adresse"].ToString(); string comments = row["Bem"].ToString(); decimal.TryParse(row["AftaltLeje"].ToString(), out decimal rentalPrice); int tenantCategoryId = GetTenantCategory(origin1); BookingDataModel booking = new BookingDataModel { BookingNumber = bookingNumber, ArrivalDate = arrivalDate, DepartureDate = departureDate, OnlySelectedWeekdays = false, SelectedWeekdays = new List <WeekdayType>(), TenantCategoryId = tenantCategoryId, TenantName = origin2, Purpose = purpose, ContactName = contactName, ContactPhone = "", ContactAddress = contactAddress, ContactCity = "", ContactEMail = contactEmail, Comments = "Importeret i 2021 fra gammelt bookingsystem\n\n" + comments, RentalPrice = Math.Abs(rentalPrice), Deposit = 0, BookingState = BookingDataModel.BookingStateType.Closed, IsApproved = true, IsCheckedOut = true, WelcomeLetterIsSent = true }; if (booking.ArrivalDate.Value.Year >= 2021) { if (status == "Forespørgsel") { booking.BookingState = BookingDataModel.BookingStateType.Requested; booking.IsApproved = false; booking.WelcomeLetterIsSent = false; booking.IsCheckedOut = false; } else if (status == "Bekræftet") { booking.BookingState = BookingDataModel.BookingStateType.Approved; booking.IsApproved = true; booking.WelcomeLetterIsSent = false; booking.IsCheckedOut = false; } else if (status == "Nøgle sendt") { booking.BookingState = BookingDataModel.BookingStateType.Approved; booking.IsApproved = true; booking.WelcomeLetterIsSent = true; booking.IsCheckedOut = false; } } var addCommand = new AddCustomEntityCommand { CustomEntityDefinitionCode = BookingCustomEntityDefinition.DefinitionCode, Model = booking, Title = booking.MakeTitle(), Publish = true }; await DomainRepository.WithElevatedPermissions().CustomEntities().AddAsync(addCommand); if (++count >= 10000) { break; } } catch (ValidationException ex) { if (ex.ValidationResult is CompositeValidationResult vres) { throw new Exception($"Failed to validate booking number {bookingGroup.Key}: {vres.Results?.FirstOrDefault()}.", ex); } else { throw new Exception($"Failed to validate booking number {bookingGroup.Key}: {ex.ValidationResult?.ErrorMessage} ({ex.ValidationResult?.MemberNames?.FirstOrDefault()}).", ex); } } catch (Exception ex) { throw new Exception($"Failed to import booking number {bookingGroup.Key}.", ex); } } //return Task.CompletedTask; }