forked from ddrilling/AsbCloudServer
217 lines
8.7 KiB
C#
217 lines
8.7 KiB
C#
using AsbCloudApp.Data;
|
||
using AsbCloudApp.Exceptions;
|
||
using AsbCloudApp.Services;
|
||
using AsbCloudDb.Model;
|
||
using AsbCloudInfrastructure.Repository;
|
||
using Mapster;
|
||
using Microsoft.EntityFrameworkCore;
|
||
using Microsoft.Extensions.Configuration;
|
||
using System;
|
||
using System.Collections.Generic;
|
||
using System.IO;
|
||
using System.Linq;
|
||
using System.Threading;
|
||
using System.Threading.Tasks;
|
||
|
||
namespace AsbCloudInfrastructure.Services
|
||
{
|
||
#nullable enable
|
||
/// <summary>
|
||
/// Сервис "Дело скважины"
|
||
/// </summary>
|
||
public class WellFinalDocumentsService : IWellFinalDocumentsService
|
||
{
|
||
private readonly IAsbCloudDbContext context;
|
||
private readonly IFileService fileService;
|
||
private readonly IUserService userService;
|
||
private readonly IWellService wellService;
|
||
private readonly IConfiguration configuration;
|
||
private readonly IEmailService emailService;
|
||
private readonly IFileCategoryService fileCategoryService;
|
||
|
||
public WellFinalDocumentsService(IAsbCloudDbContext context,
|
||
IFileService fileService,
|
||
IUserService userService,
|
||
IWellService wellService,
|
||
IConfiguration configuration,
|
||
IEmailService emailService,
|
||
IFileCategoryService fileCategoryService)
|
||
{
|
||
this.context = context;
|
||
this.fileService = fileService;
|
||
this.userService = userService;
|
||
this.wellService = wellService;
|
||
this.configuration = configuration;
|
||
this.emailService = emailService;
|
||
this.fileCategoryService = fileCategoryService;
|
||
}
|
||
|
||
public async Task<int> UpdateRangeAsync(int idWell, IEnumerable<WellFinalDocumentInputDto>? dtos, CancellationToken token)
|
||
{
|
||
if (dtos is not null)
|
||
{
|
||
var entities = dtos
|
||
.Where(dto => dto.IdsPublishers?.Any() == true)
|
||
.SelectMany(dto => dto.IdsPublishers
|
||
.Select(idUser => new WellFinalDocument
|
||
{
|
||
IdCategory = dto.IdCategory,
|
||
IdWell = idWell,
|
||
IdUser = idUser
|
||
}));
|
||
|
||
var itemsToDelete = context.WellFinalDocuments.Where(d => d.IdWell == idWell);
|
||
context.WellFinalDocuments.RemoveRange(itemsToDelete);
|
||
|
||
await context.WellFinalDocuments.AddRangeAsync(entities).ConfigureAwait(false);
|
||
var data = await context.SaveChangesAsync(token).ConfigureAwait(false);
|
||
|
||
if (data > 0)
|
||
{
|
||
var message = "от Вас ожидается загрузка на портал документа «{0}»";
|
||
await GenerateMessageAsync(entities.Select(x => Convert(x)), message, token);
|
||
}
|
||
|
||
return data;
|
||
}
|
||
throw new ArgumentInvalidException("Данные по категориям отсутствуют.");
|
||
}
|
||
|
||
public async Task<WellCaseDto> GetByWellId(int idWell, int idUser, CancellationToken token)
|
||
{
|
||
var wellFinalDocuments = new List<WellFinalDocumentDto>();
|
||
|
||
var wells = await context.WellFinalDocuments.Where(x => x.IdWell == idWell)
|
||
.ToListAsync(token)
|
||
.ConfigureAwait(false);
|
||
|
||
if (wells.Any())
|
||
{
|
||
var category = await context.FileCategories
|
||
.Where(x => wells.Select(w => w.IdCategory).Contains(x.Id))
|
||
.ToListAsync(token)
|
||
.ConfigureAwait(false);
|
||
|
||
var wellFinalDocs = category
|
||
.GroupJoin(wells,
|
||
fc => fc.Id,
|
||
w => w.IdCategory,
|
||
(o, i) => new {
|
||
IdCategory = o.Id,
|
||
NameCategory = o.Name,
|
||
Wells = i
|
||
})
|
||
.ToList();
|
||
|
||
var wellFiles = await fileService.GetInfosByWellIdAsync(idWell, token).ConfigureAwait(false);
|
||
|
||
wellFinalDocs.ForEach(async item => {
|
||
var userIds = item.Wells
|
||
.Select(x => x.IdUser)
|
||
.ToList();
|
||
var allUsers = await userService.GetAllAsync(token)
|
||
.ConfigureAwait(false);
|
||
|
||
var allFiles = wellFiles.Where(x => x.IdCategory == item.IdCategory);
|
||
|
||
FileInfoDto? actualFile = null;
|
||
if (allFiles.Any())
|
||
{
|
||
actualFile = allFiles.OrderByDescending(x => x.Id)
|
||
.FirstOrDefault();
|
||
}
|
||
|
||
var publishers = allUsers.Where(x => userIds.Contains(x.Id));
|
||
|
||
wellFinalDocuments.Add(new WellFinalDocumentDto {
|
||
IdCategory = item.IdCategory,
|
||
NameCategory = item.NameCategory,
|
||
Publishers = publishers,
|
||
FilesCount = allFiles.Count(),
|
||
File = actualFile,
|
||
PermissionToUpload = publishers.Any(x => x.Id == idUser)
|
||
});
|
||
});
|
||
}
|
||
|
||
return new WellCaseDto {
|
||
IdWell = idWell,
|
||
WellFinalDocuments = wellFinalDocuments
|
||
};
|
||
}
|
||
|
||
public async Task<IEnumerable<UserDto>> GetAvailableUsersAsync(int idWell, CancellationToken token)
|
||
{
|
||
var companyIds = await context.RelationCompaniesWells
|
||
.Where(x => x.IdWell == idWell).Select(x => x.IdCompany)
|
||
.ToListAsync(token)
|
||
.ConfigureAwait(false);
|
||
|
||
var allUsers = await userService.GetAllAsync(token)
|
||
.ConfigureAwait(false);
|
||
|
||
return allUsers.Where(x => {
|
||
var idCompany = x.IdCompany ?? default(int);
|
||
return companyIds.Contains(idCompany);
|
||
})
|
||
.OrderBy(x => x.Surname)
|
||
.ToList();
|
||
}
|
||
|
||
public async Task<int> SaveCategoryFile(int idWell, int idCategory, int idUser, Stream fileStream, string fileName, CancellationToken token)
|
||
{
|
||
var entity = await context.WellFinalDocuments
|
||
.AsNoTracking()
|
||
.FirstOrDefaultAsync(x => x.IdWell == idWell && x.IdCategory == idCategory && x.IdUser == idUser);
|
||
|
||
if (entity is null)
|
||
throw new ArgumentInvalidException("Пользователь не является ответственным за загрузку файла для данной категории.");
|
||
|
||
var dto = Convert(entity);
|
||
|
||
var file = await fileService.SaveAsync(dto.IdWell, dto.IdUser, dto.IdCategory, fileName,
|
||
fileStream, token).ConfigureAwait(false);
|
||
|
||
return file?.Id ?? -1;
|
||
}
|
||
|
||
public async Task<WellFinalDocumentsHistoryDto> GetFilesHistoryByIdCategory(int idWell, int idCategory, CancellationToken token)
|
||
{
|
||
var files = await fileService.GetInfosByCategoryAsync(idWell, idCategory, token).ConfigureAwait(false);
|
||
|
||
return new WellFinalDocumentsHistoryDto {
|
||
IdWell = idWell,
|
||
IdCategory = idCategory,
|
||
File = files
|
||
};
|
||
}
|
||
|
||
private async Task GenerateMessageAsync(IEnumerable<WellFinalDocumentDBDto> dtos, string message, CancellationToken token)
|
||
{
|
||
foreach (var item in dtos)
|
||
{
|
||
var user = await userService.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, token);
|
||
}
|
||
}
|
||
}
|
||
|
||
private void SendMessage(WellDto? well, UserDto user, string documentCategory, string message, CancellationToken token)
|
||
{
|
||
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);
|
||
}
|
||
|
||
private static WellFinalDocumentDBDto Convert(WellFinalDocument entity)
|
||
=> entity.Adapt<WellFinalDocumentDBDto>();
|
||
}
|
||
#nullable disable
|
||
}
|