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(int idUser, int idNotificationCategory, string title, string message, int idTransportType, CancellationToken cancellationToken) { var notificationCategory = await notificationCategoryRepository .GetOrDefaultAsync(idNotificationCategory, cancellationToken) ?? throw new ArgumentInvalidException("Категория уведомления не найдена", nameof(idNotificationCategory)); var notification = new NotificationDto() { IdUser = idUser, IdNotificationCategory = idNotificationCategory, Title = title, Message = message, IdTransportType = idTransportType }; notification.Id = await notificationRepository.InsertAsync(notification, cancellationToken); notification.NotificationCategory = notificationCategory; var notificationTransportService = GetNotificationTransportService(idTransportType); await notificationTransportService.SendAsync(notification, cancellationToken); await notificationRepository.UpdateAsync(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) { if (notification.SentDate == null) throw new ArgumentInvalidException("Уведомление не может быть прочитано", nameof(isRead)); notification.SentDate = DateTime.UtcNow; } 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); await notificationRepository.UpdateRangeAsync(result.Items, cancellationToken); } private INotificationTransportService GetNotificationTransportService(int idTransportType) { var notificationTransportService = notificationTransportServices .FirstOrDefault(s => s.IdTransportType == idTransportType) ?? throw new ArgumentInvalidException("Доставщик уведомлений не найден", nameof(idTransportType)); return notificationTransportService; } }