using AsbCloudApp.Data; 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; namespace AsbCloudInfrastructure.Services { #nullable enable /// /// Сервис "Дело скважины" /// public class WellFinalDocumentsService : IWellFinalDocumentsService { private readonly FileService fileService; private readonly IUserRepository userRepository; private readonly IWellService wellService; private readonly IConfiguration configuration; private readonly IEmailService emailService; private readonly IFileCategoryService fileCategoryService; private readonly IWellFinalDocumentsRepository wellFinalDocumentsRepository; private const int FileServiceThrewException = -1; public WellFinalDocumentsService(FileService fileService, IUserRepository userRepository, IWellService wellService, IConfiguration configuration, IEmailService emailService, IFileCategoryService fileCategoryService, IWellFinalDocumentsRepository wellFinalDocumentsRepository) { this.fileService = fileService; this.userRepository = userRepository; this.wellService = wellService; this.configuration = configuration; this.emailService = emailService; this.fileCategoryService = fileCategoryService; this.wellFinalDocumentsRepository = wellFinalDocumentsRepository; } /// 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); SendMessage(well, user, category.Name, message); } } } private void SendMessage(WellDto? well, UserDto user, string documentCategory, string message) { var factory = new WellFinalDocumentMailBodyFactory(configuration); var subject = factory.MakeSubject(well, documentCategory); var body = factory.MakeMailBodyForWellFinalDocument(well, user.Name ?? user.Surname, string.Format(message, documentCategory)); emailService.EnqueueSend(user.Email, subject, body); } } #nullable disable }