public async Task Should_send_correct_data() { InitializeMock(); var service = CreateService(); var(account, chargeAmount) = CreateAccountAndAmount(10000, 9943, 1, 1); AccountBalanceManagementNotificationData actualMailData = null; SaveMailData(); await service.SendNotificationIfRequired(account, chargeAmount); Assert.Equal(1, actualMailData.AgencyAccountId); Assert.Equal(1, actualMailData.AgencyId); Assert.Equal("AgencyName1", actualMailData.AgencyName); Assert.Equal(EnumFormatters.FromDescription(Currencies.USD), actualMailData.Currency); Assert.Equal(MoneyFormatter.ToCurrencyString(57, Currencies.USD), actualMailData.NewAmount); void SaveMailData() => _notificationServiceMock .Setup(x => x.Send(It.IsAny <DataWithCompanyInfo>(), It.IsAny <NotificationTypes>(), It.IsAny <string>())) .Callback <DataWithCompanyInfo, NotificationTypes, string>((data, _, _) => actualMailData = (AccountBalanceManagementNotificationData)data); }
static BookingSummaryNotificationData.BookingData CreateBookingData(Booking booking) => new BookingSummaryNotificationData.BookingData { ReferenceCode = booking.ReferenceCode, Accommodation = booking.AccommodationName, Location = $"{booking.Location.Country}, {booking.Location.Locality}", LeadingPassenger = booking.GetLeadingPassengerFormattedName(), 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), PaymentType = EnumFormatters.FromDescription(booking.PaymentType) };
public async Task SendNotificationIfRequired(AgencyAccount account, MoneyAmount chargedAmount) { var resultingBalance = account.Balance - chargedAmount.Amount; var(_, isFailure, setting, _) = await _balanceNotificationsManagementService.Get(account.Id); if (isFailure || !setting.Thresholds.Any(t => account.Balance >= t && resultingBalance < t)) { return; } var(_, isAgencyFailure, agency, _) = await _adminAgencyManagementService.Get(account.AgencyId); if (isAgencyFailure) { return; } var lowestThreshold = setting.Thresholds .Where(t => account.Balance >= t && resultingBalance < t) .OrderBy(t => t) .First(); var messageData = new AccountBalanceManagementNotificationData { AgencyAccountId = account.Id, AgencyId = agency.Id ?? 0, AgencyName = agency.Name, Currency = EnumFormatters.FromDescription(account.Currency), Threshold = lowestThreshold, NewAmount = MoneyFormatter.ToCurrencyString(resultingBalance, account.Currency) }; await _notificationService.Send(messageData : messageData, notificationType : NotificationTypes.AccountBalanceManagementNotification, email : _options.AccountsEmail); }
public async Task <Result <string> > SendBookingReports(int agencyId) { var reportBeginTime = _dateTimeProvider.UtcNow(); var reportEndTime = reportBeginTime.AddDays(1); return(await GetEmailsAndSettings() .Map(GetBookings) .Bind(CreateMailData) .Bind(SendMails)); async Task <Result <List <EmailAndSetting> > > GetEmailsAndSettings() { var rolesWithPermission = await _context.AgentRoles .Where(x => x.Permissions.HasFlag(InAgencyPermissions.ReceiveBookingSummary)) .Select(x => x.Id) .ToListAsync(); var emailsAndSettings = await (from relation in _context.AgentAgencyRelations join agent in _context.Agents on relation.AgentId equals agent.Id where relation.AgencyId == agencyId && relation.IsActive && relation.AgentRoleIds.Any(rolesWithPermission.Contains) select new EmailAndSetting { AgentId = relation.AgentId, AgencyId = relation.AgencyId, 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 bookings = await _context.Bookings .Where(b => b.AgencyId == agencyId && b.PaymentType == PaymentTypes.VirtualAccount && b.PaymentStatus != BookingPaymentStatuses.Captured && BookingStatusesForSummary.Contains(b.Status) && ((b.DeadlineDate != null) ? b.DeadlineDate : b.CheckInDate) > reportBeginTime && ((b.DeadlineDate != null) ? b.DeadlineDate : b.CheckInDate) <= reportEndTime) .ToListAsync(); return(emailsAndSettings, bookings); } async Task <Result <List <(BookingSummaryNotificationData, EmailAndSetting)> > > 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, EmailAndSetting)> >( $"Couldn't retrieve account balance for agency with id {agencyId}. Error: {error}")); } var agencyBalance = balanceInfo.Balance; return(values.emailsAndSettings.Select(emailAndSetting => { var resultingBalance = agencyBalance - values.bookings.Sum(b => b.TotalPrice); return (new BookingSummaryNotificationData { Bookings = values.bookings.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(reportBeginTime) }, emailAndSetting); }).Where(t => t.Item1.Bookings.Any()).ToList());