static BookingSummaryNotificationData.BookingData CreateBookingData(Booking booking) => new BookingSummaryNotificationData.BookingData { ReferenceCode = booking.ReferenceCode, Accommodation = booking.AccommodationName, Location = $"{booking.Location.Country}, {booking.Location.Locality}", LeadingPassenger = GetLeadingPassengerFormattedName(booking), Amount = MoneyFormatter.ToCurrencyString(booking.TotalPrice, booking.Currency), DeadlineDate = DateTimeFormatters.ToDateString(booking.DeadlineDate), CheckInDate = DateTimeFormatters.ToDateString(booking.CheckInDate), CheckOutDate = DateTimeFormatters.ToDateString(booking.CheckOutDate), Status = EnumFormatters.FromDescription(booking.Status) };
public async Task <Result <string> > SendBookingReports(int agencyId) { DateTime reportBeginDate = _dateTimeProvider.UtcNow().Date; return(await GetEmailsAndSettings() .Map(GetBookings) .Bind(CreateMailData) .Bind(SendMails)); async Task <Result <List <EmailAndSetting> > > GetEmailsAndSettings() { var emailsAndSettings = await (from relation in _context.AgentAgencyRelations join agent in _context.Agents on relation.AgentId equals agent.Id where relation.AgencyId == agencyId && relation.InAgencyPermissions.HasFlag(InAgencyPermissions.ReceiveBookingSummary) select new EmailAndSetting { Email = agent.Email, ReportDaysSetting = _agentSettingsManager.GetUserSettings(agent).BookingReportDays }).ToListAsync(); return(emailsAndSettings.Any() ? Result.Success(emailsAndSettings) : Result.Failure <List <EmailAndSetting> >($"Couldn't find any agents in agency with id {agencyId} to send summary to")); } async Task <(List <EmailAndSetting>, List <Booking>)> GetBookings(List <EmailAndSetting> emailsAndSettings) { var maxPeriod = emailsAndSettings.Max(t => t.ReportDaysSetting); var reportMaxEndDate = reportBeginDate.AddDays(maxPeriod); var bookings = await _context.Bookings.Where(b => b.AgencyId == agencyId && b.PaymentMethod == PaymentMethods.BankTransfer && b.PaymentStatus != BookingPaymentStatuses.Captured && BookingStatusesForSummary.Contains(b.Status) && b.DeadlineDate < reportMaxEndDate).ToListAsync(); return(emailsAndSettings, bookings); } async Task <Result <List <(BookingSummaryNotificationData, string)> > > CreateMailData((List <EmailAndSetting> emailsAndSettings, List <Booking> bookings) values) { var(_, isFailure, balanceInfo, error) = await _accountPaymentService.GetAccountBalance(Currencies.USD, agencyId); if (isFailure) { return(Result.Failure <List <(BookingSummaryNotificationData, string)> >( $"Couldn't retrieve account balance for agency with id {agencyId}. Error: {error}")); } var agencyBalance = balanceInfo.Balance; return(values.emailsAndSettings.Select(emailAndSetting => { var reportEndDate = reportBeginDate.AddDays(emailAndSetting.ReportDaysSetting); var includedBookings = values.bookings.Where(b => b.DeadlineDate < reportEndDate).ToList(); var resultingBalance = agencyBalance - includedBookings.Sum(b => b.TotalPrice); return (new BookingSummaryNotificationData { Bookings = includedBookings.OrderBy(b => b.DeadlineDate).Select(CreateBookingData).ToList(), CurrentBalance = MoneyFormatter.ToCurrencyString(agencyBalance, Currencies.USD), ResultingBalance = MoneyFormatter.ToCurrencyString(resultingBalance, Currencies.USD), ShowAlert = resultingBalance < 0m, ReportDate = DateTimeFormatters.ToDateString(reportEndDate) }, emailAndSetting.Email); }).Where(t => t.Item1.Bookings.Any()).ToList());