#5998816 исправление замечаний

This commit is contained in:
ai.astrakhantsev 2022-09-08 12:05:56 +05:00
parent 62eb609b20
commit 0ad4cebdb8
15 changed files with 209 additions and 169 deletions

View File

@ -1,5 +1,6 @@
namespace AsbCloudApp.Data namespace AsbCloudApp.Data
{ {
#nullable enable
/// <summary> /// <summary>
/// DTO категории файла /// DTO категории файла
/// </summary> /// </summary>
@ -18,4 +19,5 @@
/// </summary> /// </summary>
public string ShortName { get; set; } public string ShortName { get; set; }
} }
#nullable disable
} }

View File

@ -1,5 +1,6 @@
namespace AsbCloudApp.Data namespace AsbCloudApp.Data
{ {
#nullable enable
/// <summary> /// <summary>
/// DTO Дело скважины /// DTO Дело скважины
/// </summary> /// </summary>
@ -11,7 +12,7 @@
public int Id { get; set; } public int Id { get; set; }
/// <summary> /// <summary>
/// Идентификатор вышка /// Идентификатор скважины
/// </summary> /// </summary>
public int IdWell { get; set; } public int IdWell { get; set; }
@ -30,4 +31,5 @@
/// </summary> /// </summary>
public int? IdFile { get; set; } public int? IdFile { get; set; }
} }
#nullable disable
} }

View File

@ -3,31 +3,31 @@ using System.Linq;
namespace AsbCloudApp.Data namespace AsbCloudApp.Data
{ {
#nullable disable #nullable enable
/// <summary> /// <summary>
/// DTO Дело скважины /// DTO Документ дела скважины
/// </summary> /// </summary>
public class WellFinalDocumentsDto public class WellFinalDocumentsDto
{ {
/// <summary> /// <summary>
/// Вышка /// Скважина
/// </summary> /// </summary>
public int IdWell { get; set; } public int IdWell { get; set; }
/// <summary> /// <summary>
/// Наменование категории файла /// Наименование категории файла
/// </summary> /// </summary>
public string NameCategory { get; set; } public string NameCategory { get; set; }
/// <summary> /// <summary>
/// Список ответственных /// Список ответственных
/// </summary> /// </summary>
public IEnumerable<UserExtendedDto> ListResponsible { get; set; } = Enumerable.Empty<UserExtendedDto>(); public IEnumerable<UserDto> Publishers { get; set; } = Enumerable.Empty<UserDto>();
/// <summary> /// <summary>
/// Количество файлов этой категории загруженных ранее /// Количество файлов этой категории загруженных ранее
/// </summary> /// </summary>
public int CountFiles { get; set; } public int FilesCount { get; set; }
/// <summary> /// <summary>
/// Актуальный файл /// Актуальный файл

View File

@ -2,6 +2,7 @@
namespace AsbCloudApp.Data namespace AsbCloudApp.Data
{ {
#nullable enable
/// <summary> /// <summary>
/// DTO Дело скважины, история файлов /// DTO Дело скважины, история файлов
/// </summary> /// </summary>
@ -13,7 +14,7 @@ namespace AsbCloudApp.Data
public int IdWell { get; set; } public int IdWell { get; set; }
/// <summary> /// <summary>
/// Наменование категории файла /// Наименование категории файла
/// </summary> /// </summary>
public int IdCategory { get; set; } public int IdCategory { get; set; }
@ -22,4 +23,5 @@ namespace AsbCloudApp.Data
/// </summary> /// </summary>
public List<FileInfoDto> File { get; set; } public List<FileInfoDto> File { get; set; }
} }
#nullable disable
} }

View File

@ -10,6 +10,8 @@ namespace AsbCloudApp.Services
/// </summary> /// </summary>
public interface IFileCategoryService public interface IFileCategoryService
{ {
Task<FileCategoryDto> GetOrDefaultAsync(int id, CancellationToken token);
/// <summary> /// <summary>
/// Получение справочника категорий файлов /// Получение справочника категорий файлов
/// </summary> /// </summary>

View File

@ -1,14 +1,12 @@
using AsbCloudApp.Data; using AsbCloudApp.Data;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq;
using System.Text;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace AsbCloudApp.Services namespace AsbCloudApp.Services
{ {
#nullable enable
/// <summary> /// <summary>
/// Сервис "Дело скважины" /// Сервис "Дело скважины"
/// </summary> /// </summary>
@ -20,7 +18,7 @@ namespace AsbCloudApp.Services
/// <param name = "idWell" ></param > /// <param name = "idWell" ></param >
/// <param name="token"></param> /// <param name="token"></param>
/// <returns></returns> /// <returns></returns>
Task<List<WellFinalDocumentsDto>> GetByWellId(int idWell, CancellationToken token); Task<IEnumerable<WellFinalDocumentsDto>> GetByWellId(int idWell, CancellationToken token);
/// <summary> /// <summary>
/// Получение списка ответственных /// Получение списка ответственных
@ -28,23 +26,7 @@ namespace AsbCloudApp.Services
/// <param name="idWell"></param> /// <param name="idWell"></param>
/// <param name="token"></param> /// <param name="token"></param>
/// <returns></returns> /// <returns></returns>
Task<List<UserExtendedDto>> GetListResponsiblesAsync(int idWell, CancellationToken token); Task<IEnumerable<UserDto>> GetPublishersAsync(int idWell, CancellationToken token);
/// <summary>
/// Добавление записи
/// </summary>
/// <param name="dtos"></param>
/// <param name="token"></param>
/// <returns></returns>
Task<int> InsertRangeAsync(List<WellFinalDocumentsDBDto> dtos, CancellationToken token);
/// <summary>
/// Удалить запись
/// </summary>
/// <param name="dtoId"></param>
/// <param name="token"></param>
/// <returns></returns>
Task<int> DeleteAsync(int dtoId, CancellationToken token);
/// <summary> /// <summary>
/// Получение истории файлов /// Получение истории файлов
@ -53,16 +35,18 @@ namespace AsbCloudApp.Services
/// <param name="idCategory"></param> /// <param name="idCategory"></param>
/// <param name="token"></param> /// <param name="token"></param>
/// <returns></returns> /// <returns></returns>
Task<WellFinalDocumentsHistoryDto> GetHistoryFileByIdCategory(int idWell, int idCategory, CancellationToken token); Task<WellFinalDocumentsHistoryDto> GetFilesHistoryByIdCategory(int idWell, int idCategory, CancellationToken token);
/// <summary> /// <summary>
/// Сохранение файла /// Сохранение файла
/// </summary> /// </summary>
/// <param name="idDto"></param> /// <param name="idDto"></param>
/// <param name="idUser"></param>
/// <param name="fileStream"></param> /// <param name="fileStream"></param>
/// <param name="fileName"></param> /// <param name="fileName"></param>
/// <param name="token"></param> /// <param name="token"></param>
/// <returns></returns> /// <returns></returns>
Task<int> SaveCategoryFile(int idDto, Stream fileStream, string fileName, CancellationToken token); Task<int> SaveCategoryFile(int idDto, int idUser, Stream fileStream, string fileName, CancellationToken token);
} }
} #nullable disable
}

View File

@ -344,12 +344,6 @@ namespace AsbCloudDb.Model
}); });
DefaultData.DefaultContextData.Fill(modelBuilder); DefaultData.DefaultContextData.Fill(modelBuilder);
modelBuilder.Entity<WellFinalDocuments>(entity =>
{
entity.HasKey(d => new { d.Id })
.HasName("t_well_final_documents_pk");
});
} }
public Task<int> RefreshMaterializedViewAsync<TEntity>(CancellationToken token) public Task<int> RefreshMaterializedViewAsync<TEntity>(CancellationToken token)

View File

@ -359,8 +359,8 @@ namespace AsbCloudInfrastructure.Services.DrillingProgram
var file = await fileService.GetInfoAsync(fileMark.IdFile, token); var file = await fileService.GetInfoAsync(fileMark.IdFile, token);
var well = await wellService.GetOrDefaultAsync(file.IdWell, token); var well = await wellService.GetOrDefaultAsync(file.IdWell, token);
var user = file.Author; var user = file.Author;
var factory = new MailBodyFactory(configuration); var factory = new DrillingMailBodyFactory(configuration);
var subject = MailBodyFactory.MakeSubject(well, "Загруженный вами документ полностью согласован"); var subject = factory.MakeSubject(well, "Загруженный вами документ полностью согласован");
var body = factory.MakeMailBodyForPublisherOnFullAccept(well, user.Name, file.Id, file.Name); var body = factory.MakeMailBodyForPublisherOnFullAccept(well, user.Name, file.Id, file.Name);
emailService.EnqueueSend(user.Email, subject, body); emailService.EnqueueSend(user.Email, subject, body);
@ -371,8 +371,8 @@ namespace AsbCloudInfrastructure.Services.DrillingProgram
var file = await fileService.GetInfoAsync(fileMark.IdFile, token); var file = await fileService.GetInfoAsync(fileMark.IdFile, token);
var well = await wellService.GetOrDefaultAsync(file.IdWell, token); var well = await wellService.GetOrDefaultAsync(file.IdWell, token);
var user = file.Author; var user = file.Author;
var factory = new MailBodyFactory(configuration); var factory = new DrillingMailBodyFactory(configuration);
var subject = MailBodyFactory.MakeSubject(well, "Загруженный вами документ отклонен"); var subject = factory.MakeSubject(well, "Загруженный вами документ отклонен");
var body = factory.MakeMailBodyForPublisherOnReject(well, user.Name, file.Id, file.Name, fileMark); var body = factory.MakeMailBodyForPublisherOnReject(well, user.Name, file.Id, file.Name, fileMark);
emailService.EnqueueSend(user.Email, subject, body); emailService.EnqueueSend(user.Email, subject, body);
@ -381,8 +381,8 @@ namespace AsbCloudInfrastructure.Services.DrillingProgram
private async Task NotifyApproversAsync(DrillingProgramPart part, int idFile, string fileName, CancellationToken token) private async Task NotifyApproversAsync(DrillingProgramPart part, int idFile, string fileName, CancellationToken token)
{ {
var well = await wellService.GetOrDefaultAsync(part.IdWell, token); var well = await wellService.GetOrDefaultAsync(part.IdWell, token);
var factory = new MailBodyFactory(configuration); var factory = new DrillingMailBodyFactory(configuration);
var subject = MailBodyFactory.MakeSubject(well, "Загружен новый документ для согласования."); var subject = factory.MakeSubject(well, "Загружен новый документ для согласования.");
var users = part.RelatedUsers var users = part.RelatedUsers
.Where(r => r.IdUserRole == idUserRoleApprover) .Where(r => r.IdUserRole == idUserRoleApprover)
.Select(r => r.User); .Select(r => r.User);
@ -397,8 +397,8 @@ namespace AsbCloudInfrastructure.Services.DrillingProgram
private async Task NotifyNewPublisherAsync(int idWell, UserDto user, string documentCategory, CancellationToken token) private async Task NotifyNewPublisherAsync(int idWell, UserDto user, string documentCategory, CancellationToken token)
{ {
var well = await wellService.GetOrDefaultAsync(idWell, token); var well = await wellService.GetOrDefaultAsync(idWell, token);
var factory = new MailBodyFactory(configuration); var factory = new DrillingMailBodyFactory(configuration);
var subject = MailBodyFactory.MakeSubject(well, $"От вас ожидается загрузка на портал документа «{documentCategory}»"); var subject = factory.MakeSubject(well, $"От вас ожидается загрузка на портал документа «{documentCategory}»");
var body = factory.MakeMailBodyForNewPublisher(well, user.Name, documentCategory); var body = factory.MakeMailBodyForNewPublisher(well, user.Name, documentCategory);
emailService.EnqueueSend(user.Email, subject, body); emailService.EnqueueSend(user.Email, subject, body);
} }

View File

@ -0,0 +1,55 @@
using AsbCloudApp.Data;
using Microsoft.Extensions.Configuration;
using System;
using System.IO;
namespace AsbCloudInfrastructure.Services.Email
{
public class BaseFactory
{
private readonly string platformName;
private readonly string platformUrl;
private readonly string companyName;
private readonly string supportMail;
public BaseFactory(IConfiguration configuration)
{
platformName = configuration.GetValue("email:platformName", "Цифровое бурение");
platformUrl = configuration.GetValue("email:platformUrl", "https://cloud.digitaldrilling.ru/");
companyName = configuration.GetValue("email:companyName", "ООО \"Цифровое бурение\"");
supportMail = configuration.GetValue("email:supportMail", "support@digitaldrilling.ru");
}
public static string GetImageBase64(string resourceFileName)
{
if (string.IsNullOrEmpty(resourceFileName))
return null;
var baseDir = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
var resoursesDir = "Res";
var logoFilePath = Path.Combine(baseDir, resoursesDir, resourceFileName);
var imageBytes = File.ReadAllBytes(logoFilePath);
var format = Path.GetExtension(resourceFileName).Trim('.');
return "data:image/" + format + ";base64," + Convert.ToBase64String(imageBytes);
}
public static string MakeHref(string url, string text)
=> $"<a href=\"{url}\">{text}</a>";
public string MakeSignatue()
{
var logo = GetImageBase64("logo_32.png");
var sign = $"<br><br>---<br><img src=\"{logo}\"/><br>" +
$"{companyName}<br>" +
$"Это письмо сформировано автоматически.<br>" +
$"Для получения помощи по работе на портале {platformName}" +
$"обращайтесь по адресу {supportMail}";
return sign;
}
public virtual string MakeSubject(WellDto well, string action)
=> $"{well.Deposit}, {well.Cluster}, {well.Caption}. {action}";
}
}

View File

@ -1,26 +1,24 @@
using AsbCloudApp.Data; using AsbCloudApp.Data;
using AsbCloudInfrastructure.Services.Email;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using System; using System;
using System.IO; using System.IO;
namespace AsbCloudInfrastructure namespace AsbCloudInfrastructure
{ {
class MailBodyFactory class DrillingMailBodyFactory : BaseFactory
{ {
private readonly string platformName; private readonly string platformName;
private readonly string platformUrl; private readonly string platformUrl;
private readonly string companyName;
private readonly string supportMail;
public MailBodyFactory(IConfiguration configuration) public DrillingMailBodyFactory(IConfiguration configuration)
: base(configuration)
{ {
platformName = configuration.GetValue("email:platformName", "Цифровое бурение"); platformName = configuration.GetValue("email:platformName", "Цифровое бурение");
platformUrl = configuration.GetValue("email:platformUrl", "https://cloud.digitaldrilling.ru/"); platformUrl = configuration.GetValue("email:platformUrl", "https://cloud.digitaldrilling.ru/");
companyName = configuration.GetValue("email:companyName", "ООО \"Цифровое бурение\"");
supportMail = configuration.GetValue("email:supportMail", "support@digitaldrilling.ru");
} }
public static string MakeSubject(WellDto well, string action) public override string MakeSubject(WellDto well, string action)
{ {
var subj = $"{well.Deposit}, {well.Cluster}, {well.Caption}. Программа бурения. {action}"; var subj = $"{well.Deposit}, {well.Cluster}, {well.Caption}. Программа бурения. {action}";
return subj; return subj;
@ -85,34 +83,5 @@ namespace AsbCloudInfrastructure
var drillingProgramHref = MakeHref(drillingProgramUrl, well.Caption); var drillingProgramHref = MakeHref(drillingProgramUrl, well.Caption);
return drillingProgramHref; return drillingProgramHref;
} }
private static string MakeHref(string url, string text)
=> $"<a href=\"{url}\">{text}</a>";
protected string MakeSignatue()
{
var logo = GetImageBase64("logo_32.png");
var sign = $"<br><br>---<br><img src=\"{logo}\"/><br>" +
$"{companyName}<br>" +
$"Это письмо сформировано автоматически.<br>" +
$"Для получения помощи по работе на портале {platformName}" +
$"обращайтесь по адресу {supportMail}";
return sign;
}
public static string GetImageBase64(string resourceFileName)
{
if (string.IsNullOrEmpty(resourceFileName))
return null;
var baseDir = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
var resoursesDir = "Res";
var logoFilePath = Path.Combine(baseDir, resoursesDir, resourceFileName);
var imageBytes = File.ReadAllBytes(logoFilePath);
var format = Path.GetExtension(resourceFileName).Trim('.');
return "data:image/" + format + ";base64," + Convert.ToBase64String(imageBytes);
}
} }
} }

View File

@ -0,0 +1,32 @@
using AsbCloudApp.Data;
using AsbCloudInfrastructure.Services.Email;
using Microsoft.Extensions.Configuration;
using System;
using System.IO;
namespace AsbCloudInfrastructure
{
class WellFinalDocumentMailBodyFactory : BaseFactory
{
private readonly string platformName;
public WellFinalDocumentMailBodyFactory(IConfiguration configuration)
: base(configuration)
{
platformName = configuration.GetValue("email:platformName", "Цифровое бурение");
}
public override string MakeSubject(WellDto well, string action)
=> $"{well.Deposit}, {well.Cluster}, {well.Caption}. Дело скважины. {action}";
public string MakeMailBodyForWellFinalDocument(WellDto well, string publisherName, string message)
{
var body = $"<html><body><h2>Здравствуйте, {publisherName}.</h2>" +
$"На портале {platformName} {message}," +
$" куст {well.Cluster}, месторождение {well.Deposit}." +
MakeSignatue() +
$"</body></html>";
return body;
}
}
}

View File

@ -2,6 +2,7 @@
using AsbCloudApp.Services; using AsbCloudApp.Services;
using AsbCloudDb.Model; using AsbCloudDb.Model;
using AsbCloudInfrastructure.Repository; using AsbCloudInfrastructure.Repository;
using DocumentFormat.OpenXml.InkML;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
@ -35,5 +36,14 @@ namespace AsbCloudInfrastructure.Services
return data.ToList(); return data.ToList();
} }
public override async Task<FileCategoryDto> GetOrDefaultAsync(int id, CancellationToken token)
{
var entity = await db.FileCategories
.FirstOrDefaultAsync(x => x.Id == id)
.ConfigureAwait(false);
var dto = Convert(entity);
return dto;
}
} }
} }

View File

@ -1,4 +1,5 @@
using AsbCloudApp.Data; using AsbCloudApp.Data;
using AsbCloudApp.Exceptions;
using AsbCloudApp.Services; using AsbCloudApp.Services;
using AsbCloudDb.Model; using AsbCloudDb.Model;
using AsbCloudInfrastructure.Repository; using AsbCloudInfrastructure.Repository;
@ -24,13 +25,16 @@ namespace AsbCloudInfrastructure.Services
private readonly IWellService wellService; private readonly IWellService wellService;
private readonly IConfiguration configuration; private readonly IConfiguration configuration;
private readonly IEmailService emailService; private readonly IEmailService emailService;
private readonly IFileCategoryService fileCategoryService;
private const int ResultSaveCategoryFile = 0;
public WellFinalDocumentsService(IAsbCloudDbContext context, public WellFinalDocumentsService(IAsbCloudDbContext context,
IFileService fileService, IFileService fileService,
IUserService userService, IUserService userService,
IWellService wellService, IWellService wellService,
IConfiguration configuration, IConfiguration configuration,
IEmailService emailService) IEmailService emailService,
IFileCategoryService fileCategoryService)
: base(context) : base(context)
{ {
this.context = context; this.context = context;
@ -39,51 +43,43 @@ namespace AsbCloudInfrastructure.Services
this.wellService = wellService; this.wellService = wellService;
this.configuration = configuration; this.configuration = configuration;
this.emailService = emailService; this.emailService = emailService;
this.fileCategoryService = fileCategoryService;
} }
public async Task<int> InsertRangeAsync(List<WellFinalDocumentsDBDto> dtos, CancellationToken token) public override async Task<int> InsertRangeAsync(IEnumerable<WellFinalDocumentsDBDto> dtos, CancellationToken token)
{ {
var data = await base.InsertRangeAsync(dtos, token); var data = await base.InsertRangeAsync(dtos, token);
if (data > 0) if (data > 0)
{ {
// Текст сообщения var message = "от Вас ожидается загрузка на портал документа «{0}»";
var message = "От Вас ожидается загрузка на портал документа «{0}»"; await GenerateMessageAsync(dtos, message, token);
await GenerateMessage(dtos, message, token);
} }
return data; return data;
} }
public async Task<int> DeleteAsync(int dtoId, CancellationToken token) public override async Task<int> DeleteAsync(int dtoId, CancellationToken token)
{ {
// Получение данные удаляемой записи var entity = await context.WellFinalDocuments
var dtos = await context.WellFinalDocuments.Where(x => x.Id == dtoId) .AsNoTracking()
.Select(x => new WellFinalDocumentsDBDto .FirstOrDefaultAsync(x => x.Id == dtoId);
{ var dto = Convert(entity);
IdCategory = x.IdCategory,
IdWell = x.IdWell,
IdUser = x.IdUser,
IdFile = x.IdFile
})
.ToListAsync(token)
.ConfigureAwait(false);
var data = await base.DeleteAsync(dtoId, token); var data = await base.DeleteAsync(dtoId, token);
if (data > 0) if (data > 0)
{ {
// Текст сообщения
var message = "Вас удалили из ответственных за загрузку документа «{0}»"; var message = "Вас удалили из ответственных за загрузку документа «{0}»";
await GenerateMessage(dtos, message, token); await GenerateMessageAsync(new List<WellFinalDocumentsDBDto> { dto }, message, token);
} }
return data; return data;
} }
public async Task<List<WellFinalDocumentsDto>> GetByWellId(int idWell, CancellationToken token) public async Task<IEnumerable<WellFinalDocumentsDto>> GetByWellId(int idWell, CancellationToken token)
{ {
var result = new List<WellFinalDocumentsDto>(); var result = new List<WellFinalDocumentsDto>();
// Выбиираем все дела, по id скважины // Выбираем все дела, по id скважины
var wells = await context.WellFinalDocuments.Where(x => x.IdWell == idWell) var wells = await context.WellFinalDocuments.Where(x => x.IdWell == idWell)
.ToListAsync(token) .ToListAsync(token)
.ConfigureAwait(false); .ConfigureAwait(false);
@ -132,8 +128,8 @@ namespace AsbCloudInfrastructure.Services
result.Add(new WellFinalDocumentsDto { result.Add(new WellFinalDocumentsDto {
IdWell = idWell, IdWell = idWell,
NameCategory = item.NameCategory, NameCategory = item.NameCategory,
ListResponsible = allUsers.Where(x => userIds.Contains(x.Id)), Publishers = allUsers.Where(x => userIds.Contains(x.Id)),
CountFiles = fileIds.Count(x => x.HasValue), FilesCount = fileIds.Count(x => x.HasValue),
File = actualFile File = actualFile
}); });
}); });
@ -142,7 +138,7 @@ namespace AsbCloudInfrastructure.Services
return result; return result;
} }
public async Task<List<UserExtendedDto>> GetListResponsiblesAsync(int idWell, CancellationToken token) public async Task<IEnumerable<UserDto>> GetPublishersAsync(int idWell, CancellationToken token)
{ {
// Получаем отношение скважин и компаний по идентификатору скважины // Получаем отношение скважин и компаний по идентификатору скважины
var companyIds = await context.RelationCompaniesWells var companyIds = await context.RelationCompaniesWells
@ -150,7 +146,6 @@ namespace AsbCloudInfrastructure.Services
.ToListAsync(token) .ToListAsync(token)
.ConfigureAwait(false); .ConfigureAwait(false);
// Получаем пользователей
var allUsers = await userService.GetAllAsync(token) var allUsers = await userService.GetAllAsync(token)
.ConfigureAwait(false); .ConfigureAwait(false);
@ -163,42 +158,37 @@ namespace AsbCloudInfrastructure.Services
.ToList(); .ToList();
} }
public async Task<int> SaveCategoryFile(int idDto, Stream fileStream, string fileName, CancellationToken token) public async Task<int> SaveCategoryFile(int idDto, int idUser, Stream fileStream, string fileName, CancellationToken token)
{ {
// Получаем запись var entity = await context.WellFinalDocuments
var dtos = await context.WellFinalDocuments.Where(x => x.Id == idDto) .AsNoTracking()
.Select(x => new WellFinalDocumentsDBDto .FirstOrDefaultAsync(x => x.Id == idDto);
{
Id = x.Id, if (entity.IdUser != idUser)
IdCategory = x.IdCategory, throw new ArgumentInvalidException("Пользователь не является ответственным за загрузку файла для данной категории.");
IdWell = x.IdWell,
IdUser = x.IdUser, var dto = Convert(entity);
IdFile = x.IdFile
})
.ToListAsync(token)
.ConfigureAwait(false);
var dto = dtos.FirstOrDefault();
// Сохраняем файл и добавляем id файла в запись
var file = await fileService.SaveAsync(dto.IdWell, dto.IdUser, dto.IdCategory, fileName, var file = await fileService.SaveAsync(dto.IdWell, dto.IdUser, dto.IdCategory, fileName,
fileStream, token).ConfigureAwait(false); fileStream, token).ConfigureAwait(false);
if (file != null)
dto.IdFile = file.Id;
var data = await base.UpdateAsync(dto, token); if (file is not null)
return data; {
dto.IdFile = file.Id;
return await base.UpdateAsync(dto, token);
}
else return ResultSaveCategoryFile;
} }
public async Task<WellFinalDocumentsHistoryDto> GetHistoryFileByIdCategory(int idWell, int idCategory, CancellationToken token) public async Task<WellFinalDocumentsHistoryDto> GetFilesHistoryByIdCategory(int idWell, int idCategory, CancellationToken token)
{ {
// Выбиираем все id файлов, по id скважины и id категории // Выбираем все id файлов, по id скважины и id категории
var wellsIds = await context.WellFinalDocuments var wellsIds = await context.WellFinalDocuments
.Where(x => idWell == x.IdWell && x.IdCategory == idCategory && x.IdFile != null) .Where(x => idWell == x.IdWell && x.IdCategory == idCategory && x.IdFile != null)
.Select(x => (int)x.IdFile) .Select(x => (int)x.IdFile)
.ToListAsync(token) .ToListAsync(token)
.ConfigureAwait(false); .ConfigureAwait(false);
// Находим фалы
var files = await fileService.GetInfoByIdsAsync(wellsIds, token).ConfigureAwait(false); var files = await fileService.GetInfoByIdsAsync(wellsIds, token).ConfigureAwait(false);
return new WellFinalDocumentsHistoryDto { return new WellFinalDocumentsHistoryDto {
@ -208,35 +198,23 @@ namespace AsbCloudInfrastructure.Services
}; };
} }
private async Task GenerateMessage(List<WellFinalDocumentsDBDto> dtos, string message, CancellationToken token) private async Task GenerateMessageAsync(IEnumerable<WellFinalDocumentsDBDto> dtos, string message, CancellationToken token)
{ {
// Получам пользователей
var userIds = dtos.Select(x => x.IdUser);
var allUsers = await userService.GetAllAsync(token)
.ConfigureAwait(false);
var users = allUsers.Where(x => userIds.Contains(x.Id));
// Получаем категории файлов
var categoryIds = dtos.Select(x => x.IdCategory);
var category = await context.FileCategories
.Where(x => categoryIds.Contains(x.Id))
.ToListAsync(token)
.ConfigureAwait(false);
foreach (var item in dtos) foreach (var item in dtos)
{ {
var currentUser = users.FirstOrDefault(x => x.Id == item.IdUser); var user = await userService.GetOrDefaultAsync(item.IdUser, token);
var categoryName = category.FirstOrDefault(x => x.Id == item.IdCategory)?.Name; var category = await fileCategoryService.GetOrDefaultAsync(item.IdCategory, token);
await SendMessage(item.IdWell, currentUser, categoryName, message, token); var well = await wellService.GetOrDefaultAsync(item.IdWell, token);
SendMessage(well, user, category.Name, message, token);
} }
} }
private async Task SendMessage(int idWell, UserDto user, string documentCategory, string message, CancellationToken token) private void SendMessage(WellDto well, UserDto user, string documentCategory, string message, CancellationToken token)
{ {
var well = await wellService.GetOrDefaultAsync(idWell, token); var factory = new WellFinalDocumentMailBodyFactory(configuration);
var factory = new MailBodyFactory(configuration); var subject = factory.MakeSubject(well, documentCategory);
var subject = MailBodyFactory.MakeSubject(well, string.Format(message, documentCategory)); var body = factory.MakeMailBodyForWellFinalDocument(well, user.Name ?? user.Surname, string.Format(message, documentCategory));
var body = factory.MakeMailBodyForNewPublisher(well, user.Name, documentCategory);
emailService.EnqueueSend(user.Email, subject, body); emailService.EnqueueSend(user.Email, subject, body);
} }

View File

@ -9,6 +9,7 @@ using System.Threading.Tasks;
using Xunit; using Xunit;
using System.IO; using System.IO;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
namespace AsbCloudWebApi.Tests.ServicesTests namespace AsbCloudWebApi.Tests.ServicesTests
{ {
@ -21,15 +22,16 @@ namespace AsbCloudWebApi.Tests.ServicesTests
private readonly Mock<IWellService> wellServiceMock; private readonly Mock<IWellService> wellServiceMock;
private readonly Mock<IConfiguration> configurationMock; private readonly Mock<IConfiguration> configurationMock;
private readonly Mock<IEmailService> emailServiceMock; private readonly Mock<IEmailService> emailServiceMock;
private readonly Mock<IFileCategoryService> fileCategoryService;
private readonly IEnumerable<UserExtendedDto> users = new List<UserExtendedDto> { private readonly IEnumerable<UserDto> users = new List<UserDto> {
new UserExtendedDto { new UserDto {
Id = 1, Id = 1,
IdCompany = 1, IdCompany = 1,
Name = "test", Name = "test",
Email = "test@test.com" Email = "test@test.com"
}, },
new UserExtendedDto { new UserDto {
Id = 3, Id = 3,
IdCompany = 1, IdCompany = 1,
Name = "test1", Name = "test1",
@ -44,11 +46,12 @@ namespace AsbCloudWebApi.Tests.ServicesTests
fileServiceMock = new Mock<IFileService>(); fileServiceMock = new Mock<IFileService>();
userServiceMock = new Mock<IUserService>(); userServiceMock = new Mock<IUserService>();
userServiceMock.Setup(x => x.GetAllAsync(CancellationToken.None)).Returns(Task.Run(() => users)); userServiceMock.Setup(x => x.GetAllAsync(CancellationToken.None)).Returns(Task.Run(() => users.Select(x => (UserExtendedDto)x)));
wellServiceMock = new Mock<IWellService>(); wellServiceMock = new Mock<IWellService>();
configurationMock = new Mock<IConfiguration>(); configurationMock = new Mock<IConfiguration>();
emailServiceMock = new Mock<IEmailService>(); emailServiceMock = new Mock<IEmailService>();
fileCategoryService = new Mock<IFileCategoryService>();
service = new WellFinalDocumentsService( service = new WellFinalDocumentsService(
context: context, context: context,
@ -56,7 +59,8 @@ namespace AsbCloudWebApi.Tests.ServicesTests
userService: userServiceMock.Object, userService: userServiceMock.Object,
wellService: wellServiceMock.Object, wellService: wellServiceMock.Object,
configuration: configurationMock.Object, configuration: configurationMock.Object,
emailService: emailServiceMock.Object); emailService: emailServiceMock.Object,
fileCategoryService: fileCategoryService.Object);
} }
~WellFinalDocumentsServiceTest() ~WellFinalDocumentsServiceTest()
@ -73,14 +77,14 @@ namespace AsbCloudWebApi.Tests.ServicesTests
[Fact] [Fact]
public async Task GetListResponsibles_return_cnt_users() public async Task GetListResponsibles_return_cnt_users()
{ {
var data = await service.GetListResponsiblesAsync(90, CancellationToken.None); var data = await service.GetPublishersAsync(90, CancellationToken.None);
Assert.NotNull(data); Assert.NotNull(data);
} }
[Fact] [Fact]
public async Task GetHistoryFileByIdCategory_return_data_hitory() public async Task GetHistoryFileByIdCategory_return_data_hitory()
{ {
var data = await service.GetHistoryFileByIdCategory(90, 10018, CancellationToken.None); var data = await service.GetFilesHistoryByIdCategory(90, 10018, CancellationToken.None);
Assert.NotNull(data); Assert.NotNull(data);
} }

View File

@ -12,7 +12,7 @@ namespace AsbCloudWebApi.Controllers
/// <summary> /// <summary>
/// Дело скважины /// Дело скважины
/// </summary> /// </summary>
[Route("api/wellFinalDocuments")] [Route("api/[controller]")]
[ApiController] [ApiController]
[Authorize] [Authorize]
public class WellFinalDocumentsController : ControllerBase public class WellFinalDocumentsController : ControllerBase
@ -31,6 +31,7 @@ namespace AsbCloudWebApi.Controllers
/// <returns></returns> /// <returns></returns>
[HttpGet] [HttpGet]
[Permission] [Permission]
[ProducesResponseType(typeof(IEnumerable<WellFinalDocumentsDto>), (int)System.Net.HttpStatusCode.OK)]
public async Task<IActionResult> GetAsync(int idWell, CancellationToken token = default) public async Task<IActionResult> GetAsync(int idWell, CancellationToken token = default)
{ {
var data = await this.wellFinalDocumentsService.GetByWellId(idWell, token); var data = await this.wellFinalDocumentsService.GetByWellId(idWell, token);
@ -45,10 +46,11 @@ namespace AsbCloudWebApi.Controllers
/// <returns></returns> /// <returns></returns>
[HttpGet] [HttpGet]
[Permission] [Permission]
[Route("getResponsibles")] [Route("publishers")]
public async Task<IActionResult> GetResponsiblesAsync(int idWell, CancellationToken token = default) [ProducesResponseType(typeof(IEnumerable<UserDto>), (int)System.Net.HttpStatusCode.OK)]
public async Task<IActionResult> GetPublishersAsync(int idWell, CancellationToken token = default)
{ {
var data = await this.wellFinalDocumentsService.GetListResponsiblesAsync(idWell, token); var data = await this.wellFinalDocumentsService.GetPublishersAsync(idWell, token);
return Ok(data); return Ok(data);
} }
@ -60,7 +62,8 @@ namespace AsbCloudWebApi.Controllers
/// <returns></returns> /// <returns></returns>
[HttpPut] [HttpPut]
[Permission] [Permission]
public async Task<IActionResult> InsertRangeAsync(List<WellFinalDocumentsDBDto> dtos, CancellationToken token = default) [ProducesResponseType(typeof(int), (int)System.Net.HttpStatusCode.OK)]
public async Task<IActionResult> InsertRangeAsync(IEnumerable<WellFinalDocumentsDBDto> dtos, CancellationToken token = default)
{ {
var data = await this.wellFinalDocumentsService.InsertRangeAsync(dtos, token); var data = await this.wellFinalDocumentsService.InsertRangeAsync(dtos, token);
return Ok(data); return Ok(data);
@ -74,6 +77,7 @@ namespace AsbCloudWebApi.Controllers
/// <returns></returns> /// <returns></returns>
[HttpDelete] [HttpDelete]
[Permission] [Permission]
[ProducesResponseType(typeof(int), (int)System.Net.HttpStatusCode.OK)]
public async Task<IActionResult> DeleteAsync(int iDdto, CancellationToken token = default) public async Task<IActionResult> DeleteAsync(int iDdto, CancellationToken token = default)
{ {
var data = await this.wellFinalDocumentsService.DeleteAsync(iDdto, token); var data = await this.wellFinalDocumentsService.DeleteAsync(iDdto, token);
@ -89,12 +93,13 @@ namespace AsbCloudWebApi.Controllers
/// <returns></returns> /// <returns></returns>
[HttpGet] [HttpGet]
[Permission] [Permission]
[Route("getHistoryFileByIdCategory")] [Route("filesHistoryByIdCategory")]
public async Task<IActionResult> GetHistoryFileByIdCategory(int idWell, [ProducesResponseType(typeof(WellFinalDocumentsHistoryDto), (int)System.Net.HttpStatusCode.OK)]
public async Task<IActionResult> GetFilesHistoryByIdCategory(int idWell,
int idCategory, int idCategory,
CancellationToken token = default) CancellationToken token = default)
{ {
var data = await this.wellFinalDocumentsService.GetHistoryFileByIdCategory(idWell, idCategory, token); var data = await this.wellFinalDocumentsService.GetFilesHistoryByIdCategory(idWell, idCategory, token);
return Ok(data); return Ok(data);
} }
@ -102,17 +107,18 @@ namespace AsbCloudWebApi.Controllers
/// Сохранение файла /// Сохранение файла
/// </summary> /// </summary>
/// <param name="idDto"></param> /// <param name="idDto"></param>
/// <param name="idUser"></param>
/// <param name="file"></param> /// <param name="file"></param>
/// <param name="token"></param> /// <param name="token"></param>
/// <returns></returns> /// <returns></returns>
[HttpPost] [HttpPost]
[Permission] [Permission]
[ProducesResponseType(typeof(int), (int)System.Net.HttpStatusCode.OK)] [ProducesResponseType(typeof(int), (int)System.Net.HttpStatusCode.OK)]
public async Task<IActionResult> SaveFilesAsync(int idDto, public async Task<IActionResult> SaveCategoryFile(int idDto, int idUser,
IFormFile file, CancellationToken token = default) IFormFile file, CancellationToken token = default)
{ {
var fileStream = file.OpenReadStream(); var fileStream = file.OpenReadStream();
var data = await this.wellFinalDocumentsService.SaveCategoryFile(idDto, fileStream, file.FileName, token); var data = await this.wellFinalDocumentsService.SaveCategoryFile(idDto, idUser, fileStream, file.FileName, token);
return Ok(data); return Ok(data);
} }
} }