using System; using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; using AsbCloudApp.Data; using AsbCloudApp.Exceptions; using AsbCloudApp.Repositories; using AsbCloudApp.Requests; namespace AsbCloudApp.Services.Notifications; /// /// Сервис для работы с уведомлениями /// public class NotificationService { private readonly ICrudRepository notificationCategoryRepository; private readonly INotificationRepository notificationRepository; private readonly IEnumerable notificationTransportServices; /// /// Сервис для работы с уведомлениями /// /// /// /// public NotificationService(ICrudRepository notificationCategoryRepository, INotificationRepository notificationRepository, IEnumerable notificationTransportServices) { this.notificationCategoryRepository = notificationCategoryRepository; this.notificationRepository = notificationRepository; this.notificationTransportServices = notificationTransportServices; } /// /// Отправка нового уведомления /// /// /// public async Task NotifyAsync(NotifyRequest request, CancellationToken cancellationToken) { var notificationCategory = await notificationCategoryRepository .GetOrDefaultAsync(request.IdNotificationCategory, cancellationToken) ?? throw new ArgumentInvalidException("Категория уведомления не найдена", nameof(request.IdNotificationCategory)); var notification = new NotificationDto { IdUser = request.IdUser, RegistrationDate = DateTime.UtcNow, IdNotificationCategory = notificationCategory.Id, Title = request.Title, Message = request.Message, IdTransportType = request.IdTransportType, }; notification.Id = await notificationRepository.InsertAsync(notification, cancellationToken); notification.NotificationCategory = notificationCategory; var notificationTransportService = GetNotificationTransportService(request.IdTransportType); await notificationTransportService.SendAsync(notification, cancellationToken); } /// /// Обновление уведомления /// /// /// /// /// public async Task UpdateNotificationAsync(int idNotification, bool isRead, CancellationToken cancellationToken) { var notification = await notificationRepository.GetOrDefaultAsync(idNotification, cancellationToken) ?? throw new ArgumentInvalidException("Уведомление не найдено", nameof(idNotification)); if(isRead && !notification.SentDate.HasValue) throw new ArgumentInvalidException("Уведомление не может быть прочитано", nameof(isRead)); notification.ReadDate = isRead ? DateTime.UtcNow : null; await notificationRepository.UpdateAsync(notification, cancellationToken); } /// /// Отправка уведомлений, которые не были отправлены /// /// /// /// /// public async Task ResendNotificationAsync(int idUser, NotificationRequest request, CancellationToken cancellationToken) { if (!request.IdTransportType.HasValue) throw new ArgumentInvalidException("Id типа доставки уведомления должен иметь значение", nameof(request.IdTransportType)); var result = await notificationRepository.GetNotificationsAsync(idUser, request, cancellationToken); var notificationTransportService = GetNotificationTransportService(request.IdTransportType.Value); await notificationTransportService.SendRangeAsync(result.Items, cancellationToken); } private INotificationTransportService GetNotificationTransportService(int idTransportType) { var notificationTransportService = notificationTransportServices .FirstOrDefault(s => s.IdTransportType == idTransportType) ?? throw new ArgumentInvalidException("Доставщик уведомлений не найден", nameof(idTransportType)); return notificationTransportService; } }