diff --git a/AsbCloudInfrastructure/Services/DrillingProgram/DrillingProgramService.cs b/AsbCloudInfrastructure/Services/DrillingProgram/DrillingProgramService.cs index 3771ad34..d53797cb 100644 --- a/AsbCloudInfrastructure/Services/DrillingProgram/DrillingProgramService.cs +++ b/AsbCloudInfrastructure/Services/DrillingProgram/DrillingProgramService.cs @@ -24,6 +24,8 @@ namespace AsbCloudInfrastructure.Services.DrillingProgram private readonly IWellService wellService; private readonly IConfiguration configuration; private readonly IBackgroundWorkerService backgroundWorker; + //email + private readonly IEmailService emailService; private readonly string connectionString; private const int idFileCategoryDrillingProgram = 1000; @@ -52,8 +54,9 @@ namespace AsbCloudInfrastructure.Services.DrillingProgram IUserService userService, IWellService wellService, IConfiguration configuration, - IBackgroundWorkerService backgroundWorker) - { + IBackgroundWorkerService backgroundWorker, + IEmailService emailService) + { this.context = context; this.fileService = fileService; this.userService = userService; @@ -61,6 +64,7 @@ namespace AsbCloudInfrastructure.Services.DrillingProgram this.configuration = configuration; this.backgroundWorker = backgroundWorker; this.connectionString = configuration.GetConnectionString("DefaultConnection"); + this.emailService = emailService; } public async Task> GetAvailableUsers(int idWell, CancellationToken token = default) @@ -154,7 +158,8 @@ namespace AsbCloudInfrastructure.Services.DrillingProgram await TryEnqueueMakeProgramAsync(idWell, state, token); return state; } - + + public async Task AddFile(int idWell, int idFileCategory, int idUser, string fileFullName, System.IO.Stream fileStream, CancellationToken token = default) { var part = await context.DrillingProgramParts @@ -176,6 +181,35 @@ namespace AsbCloudInfrastructure.Services.DrillingProgram token); await RemoveDrillingProgramAsync(part.IdWell, token); + var well = await context.Wells + .FirstOrDefaultAsync(x => x.Id == idWell, token); + var cluster = await context.Clusters + .FirstOrDefaultAsync(x => x.Wells == well, token); + + var deposit = await context.Deposits + .FirstOrDefaultAsync(x => x.Clusters == cluster, token); + var partApprovers = await context.RelationDrillingProgramPartUsers + .Where(y => y.IdDrillingProgramPart == part.Id & y.IdUserRole == idUserRoleApprover).ToListAsync(token); + foreach (var partApprover in partApprovers) + { + var approver = await context.Users + .FirstOrDefaultAsync(x => x.Id == partApprover.IdUser, token); + + var bodyHtml = new MailCoordinating() + { + idWell=idWell, + idDocument = result.Id, + documentName = fileFullName, + wellName = well.Caption, + clusterName = cluster.Caption, + fieldName = deposit.Caption, + userName = $"{approver.Name} {approver.Surname}" + + + }; + emailService.EnqueueSend(new List {approver.Email}, bodyHtml.mailSubject, bodyHtml.GetBodyHTML()); + //emailService.EnqueueSend(new List { "79827873134@yandex.ru" }, bodyHtml.mailSubject, bodyHtml.GetBodyHTML()); + } return result.Id; } @@ -242,10 +276,35 @@ namespace AsbCloudInfrastructure.Services.DrillingProgram IdDrillingProgramPart = part.Id, IdUserRole = idUserRole, }; - + var well = await context.Wells + .FirstOrDefaultAsync(x => x.Id == idWell, token); + var cluster = await context.Clusters + .FirstOrDefaultAsync(x => x.Wells == well, token); + context.RelationDrillingProgramPartUsers.Add(newRelation); + var deposit = await context.Deposits + .FirstOrDefaultAsync(x => x.Clusters == cluster, token); + var documentCategory = await context.FileCategories + .FirstOrDefaultAsync(x => x.Id == part.IdFileCategory, token); context.RelationDrillingProgramPartUsers.Add(newRelation); if (idUserRole == idUserRoleApprover) await RemoveDrillingProgramAsync(part.IdWell, token); + // проверяем роль пользователя - если публикатор формируем для него сообщение на отправку + if (idUserRole == idUserRolePublisher) + { + //создаем тело письма + var bodyHtml = new MailUserPublisher() + { + idWell=idWell, + userName = $"{user.Name} {user.Surname}", + wellName = well.Caption, + clusterName = cluster.Caption, + fieldName = deposit.Caption, + documentCategory = documentCategory.Name + }; + + emailService.EnqueueSend(new List {user.Email}, bodyHtml.mailSubject, bodyHtml.GetBodyHTML()); + //emailService.EnqueueSend(new List { "79827873134@yandex.ru" }, bodyHtml.mailSubject, bodyHtml.GetBodyHTML()); + } return await context.SaveChangesAsync(token); } @@ -263,6 +322,9 @@ namespace AsbCloudInfrastructure.Services.DrillingProgram return await context.SaveChangesAsync(token); } + // 4 trigger?? + + public async Task AddOrReplaceFileMarkAsync(FileMarkDto fileMarkDto, int idUser, CancellationToken token) { if (fileMarkDto.IdMarkType != idMarkTypeApprove && @@ -297,7 +359,74 @@ namespace AsbCloudInfrastructure.Services.DrillingProgram .ConfigureAwait(false); if (fileMarkDto.IdMarkType == idMarkTypeReject) + { await RemoveDrillingProgramAsync(fileInfo.IdWell, token); + + var user = await context.Users + .FirstOrDefaultAsync(x => x.Id == idUser, token); + var well = await context.Wells + .FirstOrDefaultAsync(x => x.Id == part.IdWell, token); + var cluster = await context.Clusters + .FirstOrDefaultAsync(x => x.Wells == well, token); + + var deposit = await context.Deposits + .FirstOrDefaultAsync(x => x.Clusters == cluster, token); + var document = await context.Files + .FirstOrDefaultAsync(x => x.Id == fileMarkDto.IdFile, token); + var author = await context.Users + .FirstOrDefaultAsync(x => x.Id == document.IdAuthor, token); + + var bodyHtml = new PublisherRejected + { + idWell=well.Id, + idDocument=document.Id, + coordinatingName = $"{user.Name} {user.Surname}", + coordinatingComment = fileMarkDto.Comment, + wellName = well.Caption, + clusterName = cluster.Caption, + fieldName = deposit.Caption, + documentName = document.Name, + userName = $"{author.Name} {author.Surname}" + }; + + emailService.EnqueueSend(new List { author.Email }, bodyHtml.mailSubject, bodyHtml.GetBodyHTML()); + //emailService.EnqueueSend(new List { "79827873134@yandex.ru" }, bodyHtml.mailSubject, bodyHtml.GetBodyHTML()); + } + + // если все части согласованы уведомляем публикатора + if (part.RelatedUsers + .Where(u => u.IdUserRole == idUserRoleApprover) + .All(user => fileInfo.FileMarks + .Any(mark => mark.IdMarkType == idMarkTypeApprove && mark.User.Id == user.IdUser))) + { + var well = await context.Wells + .FirstOrDefaultAsync(x => x.Id == part.IdWell, token); + var cluster = await context.Clusters + .FirstOrDefaultAsync(x => x.Wells == well, token); + + var deposit = await context.Deposits + .FirstOrDefaultAsync(x => x.Clusters == cluster, token); + var document = await context.Files + .FirstOrDefaultAsync(x => x.Id == fileMarkDto.IdFile, token); + var author = await context.Users + .FirstOrDefaultAsync(x => x.Id == document.IdAuthor, token); + var documentCategory = await context.FileCategories + .FirstOrDefaultAsync(x => x.Id == part.IdFileCategory, token); + var bodyHtml = new AllApprovals + { + idWell=well.Id, + idDocument=document.Id, + documentCategory = documentCategory.Name, + wellName = well.Caption, + clusterName = cluster.Caption, + fieldName = deposit.Caption, + documentName = document.Name, + userName = $"{author.Name} {author.Surname}" + }; + emailService.EnqueueSend(new List { author.Email }, bodyHtml.mailSubject, bodyHtml.GetBodyHTML()); + //emailService.EnqueueSend(new List { "79827873134@yandex.ru" }, bodyHtml.mailSubject, bodyHtml.GetBodyHTML()); + } + return result; } diff --git a/AsbCloudInfrastructure/Services/Email/CreationBody.cs b/AsbCloudInfrastructure/Services/Email/CreationBody.cs new file mode 100644 index 00000000..25405f55 --- /dev/null +++ b/AsbCloudInfrastructure/Services/Email/CreationBody.cs @@ -0,0 +1,96 @@ +using System; +using System.Collections.Generic; + +namespace AsbCloudInfrastructure +{ + + abstract class BodyCreation + { + public int idWell { get; set; } + public int idDocument { get; set; } + public string mailSubject { get; set; } = "#fieldName, #clusterName, #wellName. Программа бурения. #action."; + public string wellName { get; set; } + public string clusterName { get; set; } + public string fieldName { get; set; } + public string documentCategory { get; set; } + public string documentName { get; set; } + public string coordinatingName { get; set; } + public string coordinatingComment { get; set; } + public string userName { get; set; } + public static string logo { get; } = "data:image/png;base64,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"; + public static string bodySign { get; } = $"



" + + $"{companyName}
Это письмо сформировано автоматически.
Для получения помощи по работе на портале " + + $"{webPlatform} обращайтесь по адресу {supportMail}
"; + public static string webPlatform { get; } = ""; + public static string companyName { get; } = "ООО \"НафтаГаз\""; + public static string supportMail { get; } = "support@autodrilling.ru"; + public abstract string GetBodyHTML(); + + } + + class MailUserPublisher : BodyCreation + { + public override string GetBodyHTML() + { + mailSubject = mailSubject.Replace("#fieldName", fieldName); + mailSubject = mailSubject.Replace("#clusterName", clusterName); + mailSubject = mailSubject.Replace("#wellName", fieldName); + mailSubject = mailSubject.Replace("#action", "Добавление публикатора"); + return $"
Здравствуйте, {userName}.

< font size = \"5\">На портале " + + $"{webPlatform} началось создание программы бурения скважины {wellName}, " + + $"куст {clusterName}, месторождение {fieldName}." + + $"

От вас ожидается загрузка на портал документа «{documentCategory}» в формате excel (*.xlsx)." + bodySign; + } + + + } + + class MailCoordinating : BodyCreation + { + public override string GetBodyHTML() + { + mailSubject = mailSubject.Replace("#fieldName", fieldName); + mailSubject = mailSubject.Replace("#clusterName", clusterName); + mailSubject = mailSubject.Replace("#wellName", fieldName); + mailSubject = mailSubject.Replace("#action", "Документ на согласование"); + return $"
Здравствуйте, {userName}.

На портал " + + $"{webPlatform} загружен документ " + + $" для согласования при создании программы бурения скважины , куст ({clusterName})" + + $", месторождение ({fieldName})." + bodySign; + } + } + + class PublisherRejected : BodyCreation + { + public override string GetBodyHTML() + { + mailSubject = mailSubject.Replace("#fieldName", fieldName); + mailSubject = mailSubject.Replace("#clusterName", clusterName); + mailSubject = mailSubject.Replace("#wellName", fieldName); + mailSubject = mailSubject.Replace("#action", "Документ отклонен"); + return $"
Здравствуйте, {userName}.

На портале " + + $"{webPlatform} отклонен загруженный вами документ
" + + $" по программе бурения скважины , куст " + + $"({clusterName}), месторождение ({fieldName}). Комментарий согласующего " + + $"({coordinatingName}):

{coordinatingComment}" + bodySign; + } + } + + class AllApprovals : BodyCreation + { + public override string GetBodyHTML() + { + mailSubject = mailSubject.Replace("#fieldName", fieldName); + mailSubject = mailSubject.Replace("#clusterName", clusterName); + mailSubject = mailSubject.Replace("#wellName", fieldName); + mailSubject = mailSubject.Replace("#action", "Все документы согласованы"); + return $"
Здравствуйте, {userName}.

На портале " + + $"{webPlatform} полностью согласован документ " + + $"
{documentName} " + + $"по программе бурения скважины , куст ({clusterName}), " + + $"месторождение ({fieldName}).
От вас ожидается загрузка на портал документа " + + $"«{documentCategory}» в формате excel (*.xlsx)." + bodySign; + } + } +} + diff --git a/AsbCloudInfrastructure/Services/EmailService.cs b/AsbCloudInfrastructure/Services/Email/EmailService.cs similarity index 96% rename from AsbCloudInfrastructure/Services/EmailService.cs rename to AsbCloudInfrastructure/Services/Email/EmailService.cs index dac8e438..d71543bd 100644 --- a/AsbCloudInfrastructure/Services/EmailService.cs +++ b/AsbCloudInfrastructure/Services/Email/EmailService.cs @@ -76,8 +76,9 @@ namespace AsbCloudInfrastructure.Services foreach (var mailAddress in mailAddresses) message.To.Add(mailAddress); - message.Subject = subject; + message.Body = htmlBody; + message.Subject = subject; message.IsBodyHtml = true; var client = new SmtpClient(smtpServer); @@ -86,9 +87,9 @@ namespace AsbCloudInfrastructure.Services client.Credentials = new System.Net.NetworkCredential(sender, smtpPassword); // TODO: uncomment next when tested - //await client.SendMailAsync(message, token); + await client.SendMailAsync(message, token); await Task.Delay(0); - Trace.TraceInformation($"Send email to {string.Join(',', addresses)} subj:{subject}"); + Trace.TraceInformation($"Send email to {string.Join(',', addresses)} subj:{subject} html body count {htmlBody.Count()}"); }; return func; } diff --git a/AsbCloudInfrastructure/Services/Email/logo_32.png b/AsbCloudInfrastructure/Services/Email/logo_32.png new file mode 100644 index 00000000..827f705d Binary files /dev/null and b/AsbCloudInfrastructure/Services/Email/logo_32.png differ diff --git a/AsbCloudWebApi.Tests/ServicesTests/DrillingProgramServiceTest.cs b/AsbCloudWebApi.Tests/ServicesTests/DrillingProgramServiceTest.cs index ffd39dd2..29eec8c9 100644 --- a/AsbCloudWebApi.Tests/ServicesTests/DrillingProgramServiceTest.cs +++ b/AsbCloudWebApi.Tests/ServicesTests/DrillingProgramServiceTest.cs @@ -83,6 +83,7 @@ namespace AsbCloudWebApi.Tests.ServicesTests private readonly Mock wellServiceMock; private readonly Mock configurationMock; private readonly Mock backgroundWorkerMock; + private readonly Mock emailService; public DrillingProgramServiceTest() { @@ -112,7 +113,8 @@ namespace AsbCloudWebApi.Tests.ServicesTests userServiceMock.Object, wellServiceMock.Object, configurationMock.Object, - backgroundWorkerMock.Object); + backgroundWorkerMock.Object, + emailService.Object); var users = await service.GetAvailableUsers(idWell, CancellationToken.None); @@ -128,7 +130,8 @@ namespace AsbCloudWebApi.Tests.ServicesTests userServiceMock.Object, wellServiceMock.Object, configurationMock.Object, - backgroundWorkerMock.Object); + backgroundWorkerMock.Object, + emailService.Object); var result = await service.AddPartsAsync(idWell, new int[] { 1001, 1002 }, CancellationToken.None); @@ -146,7 +149,8 @@ namespace AsbCloudWebApi.Tests.ServicesTests userServiceMock.Object, wellServiceMock.Object, configurationMock.Object, - backgroundWorkerMock.Object); + backgroundWorkerMock.Object, + emailService.Object); var result = await service.RemovePartsAsync(idWell, new int[] { 1005 }, CancellationToken.None); @@ -168,7 +172,8 @@ namespace AsbCloudWebApi.Tests.ServicesTests userServiceMock.Object, wellServiceMock.Object, configurationMock.Object, - backgroundWorkerMock.Object); + backgroundWorkerMock.Object, + emailService.Object); var result = await service.AddUserAsync(idWell, 1001, publisher1.Id, 1, CancellationToken.None); @@ -201,7 +206,8 @@ namespace AsbCloudWebApi.Tests.ServicesTests userServiceMock.Object, wellServiceMock.Object, configurationMock.Object, - backgroundWorkerMock.Object); + backgroundWorkerMock.Object, + emailService.Object); var result = await service.RemoveUserAsync(idWell, idFileCategory, publisher1.Id, idUserRole, CancellationToken.None); @@ -226,7 +232,8 @@ namespace AsbCloudWebApi.Tests.ServicesTests userServiceMock.Object, wellServiceMock.Object, configurationMock.Object, - backgroundWorkerMock.Object); + backgroundWorkerMock.Object, + emailService.Object); var fileMark = new FileMarkDto { @@ -256,7 +263,8 @@ namespace AsbCloudWebApi.Tests.ServicesTests userServiceMock.Object, wellServiceMock.Object, configurationMock.Object, - backgroundWorkerMock.Object); + backgroundWorkerMock.Object, + emailService.Object); var fileMark = new FileMarkDto { IdFile = file1001.Id, @@ -293,7 +301,8 @@ namespace AsbCloudWebApi.Tests.ServicesTests userServiceMock.Object, wellServiceMock.Object, configurationMock.Object, - backgroundWorkerMock.Object); + backgroundWorkerMock.Object, + emailService.Object); var fileMark = new FileMarkDto { @@ -319,7 +328,8 @@ namespace AsbCloudWebApi.Tests.ServicesTests userServiceMock.Object, wellServiceMock.Object, configurationMock.Object, - backgroundWorkerMock.Object); + backgroundWorkerMock.Object, + emailService.Object); var state = await service.GetStateAsync(idWell, publisher1.Id, CancellationToken.None); @@ -345,7 +355,8 @@ namespace AsbCloudWebApi.Tests.ServicesTests userServiceMock.Object, wellServiceMock.Object, configurationMock.Object, - backgroundWorkerMock.Object); + backgroundWorkerMock.Object, + emailService.Object); var state = await service.GetStateAsync(idWell, publisher1.Id, CancellationToken.None); @@ -374,7 +385,8 @@ namespace AsbCloudWebApi.Tests.ServicesTests userServiceMock.Object, wellServiceMock.Object, configurationMock.Object, - backgroundWorkerMock.Object); + backgroundWorkerMock.Object, + emailService.Object); var state = await service.GetStateAsync(idWell, publisher1.Id, CancellationToken.None);