using AsbCloudApp.Data; using AsbCloudApp.Data.User; using AsbCloudApp.Exceptions; using AsbCloudApp.Repositories; using AsbCloudApp.Requests; using AsbCloudApp.Services; using Microsoft.Extensions.Configuration; using System.Collections.Generic; using System.IO; using System.Linq; using System.Threading; using System.Threading.Tasks; using AsbCloudApp.Services.Notifications; using AsbCloudDb.Model; namespace AsbCloudInfrastructure.Services; /// /// Сервис "Дело скважины" /// public class WellFinalDocumentsService : IWellFinalDocumentsService { private readonly FileService fileService; private readonly IUserRepository userRepository; private readonly IWellService wellService; private readonly IConfiguration configuration; private readonly IFileCategoryService fileCategoryService; private readonly IWellFinalDocumentsRepository wellFinalDocumentsRepository; private readonly NotificationService notificationService; public WellFinalDocumentsService(FileService fileService, IUserRepository userRepository, IWellService wellService, IConfiguration configuration, IFileCategoryService fileCategoryService, IWellFinalDocumentsRepository wellFinalDocumentsRepository, NotificationService notificationService) { this.fileService = fileService; this.userRepository = userRepository; this.wellService = wellService; this.configuration = configuration; this.fileCategoryService = fileCategoryService; this.wellFinalDocumentsRepository = wellFinalDocumentsRepository; this.notificationService = notificationService; } /// public async Task UpdateRangeAsync(int idWell, IEnumerable dtos, CancellationToken token) { var data = await wellFinalDocumentsRepository.UpdateRangeAsync(idWell, dtos, token); var message = "от Вас ожидается загрузка на портал документа «{0}»"; await NotifyUsersAsync(data, message, token); return data.Count(); } /// public async Task SaveCategoryFileAsync(int idWell, int idCategory, int idUser, Stream fileStream, string fileName, CancellationToken token) { var dto = await wellFinalDocumentsRepository.GetCategoryAsync(idWell, idCategory, idUser, token) .ConfigureAwait(false); var file = await fileService.SaveAsync(dto.IdWell, dto.IdUser, dto.IdCategory, fileName, fileStream, token).ConfigureAwait(false); return file.Id; } /// public async Task GetFilesHistoryByIdCategoryAsync(int idWell, int idCategory, CancellationToken token) { var request = new FileRequest { IdWell = idWell, IdCategory = idCategory, }; var files = await fileService.GetInfosAsync(request, token).ConfigureAwait(false); return new WellFinalDocumentsHistoryDto { IdWell = idWell, IdCategory = idCategory, Files = files }; } /// public async Task ReNotifyPublishersAsync(int idWell, int idUser, int idCategory, CancellationToken token) { var wellCase = await wellFinalDocumentsRepository.GetByWellIdAsync(idWell, idUser, token); if (!wellCase.PermissionToSetPubliher) throw new ForbidException("Повторная отправка оповещений Вам не разрешена"); var requester = await userRepository.GetOrDefaultAsync(idUser, token); if (requester is null) throw new ForbidException("Не удается вас опознать"); var docs = wellCase.WellFinalDocuments .Where(doc => doc.IdCategory == idCategory) .Where(doc => doc.File is null) .SelectMany(doc => doc.Publishers .Select(pub => new WellFinalDocumentDBDto { IdCategory = idCategory, IdUser = pub.Id, IdWell = idWell })); if(!docs.Any()) throw new ArgumentInvalidException(nameof(idCategory), "Нет такой категории, или в нее уже загружен документ"); var message = requester.MakeDisplayName() + " ожидает от Вас загрузку на портал документа «{{0}}»"; await NotifyUsersAsync(docs, message, token); return docs.Count(); } private async Task NotifyUsersAsync(IEnumerable dtos, string message, CancellationToken token) { foreach (var item in dtos) { var user = await userRepository.GetOrDefaultAsync(item.IdUser, token); if (user?.Email is not null) { var category = await fileCategoryService.GetOrDefaultAsync(item.IdCategory, token); var well = await wellService.GetOrDefaultAsync(item.IdWell, token) ?? throw new ArgumentInvalidException(nameof(item.IdWell), "idWell doesn`t exist"); await SendMessageAsync(well, user, category?.Name ?? string.Empty, message, token); } } } private async Task SendMessageAsync(WellDto well, UserDto user, string documentCategory, string message, CancellationToken cancellationToken) { const int idTransportType = 1; var factory = new WellFinalDocumentMailBodyFactory(configuration); var subject = factory.MakeSubject(well, documentCategory); var body = factory.MakeMailBodyForWellFinalDocument( well, (user.Name ?? user.Surname ?? string.Empty), string.Format(message, documentCategory) ); await notificationService.NotifyAsync(new NotifyRequest { IdUser = user.Id, IdNotificationCategory = NotificationCategory.IdSystemNotificationCategory, Title = subject, Message = body, IdTransportType = idTransportType }, cancellationToken); } }