DD.WellWorkover.Cloud/AsbCloudInfrastructure/Services/WellFinalDocumentsService.cs
2022-11-18 14:48:10 +05:00

209 lines
8.4 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using AsbCloudApp.Data;
using AsbCloudApp.Exceptions;
using AsbCloudApp.Repositories;
using AsbCloudApp.Requests;
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 FileService fileService;
private readonly IUserRepository userRepository;
private readonly IWellService wellService;
private readonly IConfiguration configuration;
private readonly IEmailService emailService;
private readonly IFileCategoryService fileCategoryService;
private const int FileServiceThrewException = -1;
public WellFinalDocumentsService(IAsbCloudDbContext context,
FileService fileService,
IUserRepository userRepository,
IWellService wellService,
IConfiguration configuration,
IEmailService emailService,
IFileCategoryService fileCategoryService)
{
this.context = context;
this.fileService = fileService;
this.userRepository = userRepository;
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 entities = await context.WellFinalDocuments
.Include(d => d.Category)
.Include(d => d.User)
.Where(d => d.IdWell == idWell)
.AsNoTracking()
.ToArrayAsync(token)
.ConfigureAwait(false);
var entitiesGroups = entities
.GroupBy(d => d.IdCategory);
var categoriesIds = entitiesGroups
.Select(g => g.Key);
var files = (await fileService
.GetInfosAsync(new FileRequest { IdWell = idWell}, token)
.ConfigureAwait(false))
.Where(f => categoriesIds.Contains(f.IdCategory))
.ToArray();
var docs = entitiesGroups.Select((g) => new WellFinalDocumentDto
{
IdCategory = g.Key,
FilesCount = files
.Where(f => f.IdCategory == g.Key)
.Count(),
File = files
.Where(f => f.IdCategory == g.Key)
.OrderBy(f => f.UploadDate)
.LastOrDefault(),
NameCategory = g.First().Category.Name,
Publishers = g.Select(i => i.User.Adapt<UserDto>()),
PermissionToUpload = g.Any(i => i.IdUser == idUser),
});
var result = new WellCaseDto
{
IdWell = idWell,
PermissionToSetPubliher = userRepository.HasPermission(idUser, "WellFinalDocuments.editPublisher"),
WellFinalDocuments = docs,
};
return result;
}
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 userRepository.GetAllAsync(token)
.ConfigureAwait(false);
return allUsers.Where(x => {
var idCompany = x.IdCompany ?? default(int);
return companyIds.Contains(idCompany);
})
.OrderBy(x => x.Surname)
.ToArray();
}
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 ?? FileServiceThrewException; //TODO: изменить когда файловый сервис будет переведен на nullable
}
public async Task<WellFinalDocumentsHistoryDto> GetFilesHistoryByIdCategory(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,
File = files
};
}
private async Task GenerateMessageAsync(IEnumerable<WellFinalDocumentDBDto> 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, 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
}