using AsbCloudApp.Data;
using AsbCloudApp.Services;
using AsbCloudDb.Model;
using AsbCloudInfrastructure.Repository;
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
{
///
/// Сервис "Дело скважины"
///
public class WellFinalDocumentsService : CrudServiceBase, 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;
public WellFinalDocumentsService(IAsbCloudDbContext context,
IFileService fileService,
IUserService userService,
IWellService wellService,
IConfiguration configuration,
IEmailService emailService)
: base(context)
{
this.context = context;
this.fileService = fileService;
this.userService = userService;
this.wellService = wellService;
this.configuration = configuration;
this.emailService = emailService;
}
public async Task InsertRangeAsync(List dtos, CancellationToken token)
{
var data = await base.InsertRangeAsync(dtos, token);
if (data > 0)
{
// Текст сообщения
var message = "От Вас ожидается загрузка на портал документа «{0}»";
await GenerateMessage(dtos, message, token);
}
return data;
}
public async Task DeleteAsync(int dtoId, CancellationToken token)
{
// Получение данные удаляемой записи
var dtos = await context.WellFinalDocuments.Where(x => x.Id == dtoId)
.Select(x => new WellFinalDocumentsDBDto
{
IdCategory = x.IdCategory,
IdWell = x.IdWell,
IdUser = x.IdUser,
IdFile = x.IdFile
})
.ToListAsync(token)
.ConfigureAwait(false);
var data = await base.DeleteAsync(dtoId, token);
if (data > 0)
{
// Текст сообщения
var message = "Вас удалили из ответственных за загрузку документа «{0}»";
await GenerateMessage(dtos, message, token);
}
return data;
}
public async Task> GetByWellId(int idWell, CancellationToken token)
{
var result = new List();
// Выбиираем все дела, по id скважины
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 {
NameCategory = o.Name,
Wells = i
})
.ToList();
wellFinalDocs.ForEach(async item => {
// Получение списка ответственных
var userIds = item.Wells
.Select(x => x.IdUser)
.ToList();
var allUsers = await userService.GetAllAsync(token)
.ConfigureAwait(false);
// Получение общее количество файлов и актуальный
var fileIds = item.Wells
.Where(x => x.IdFile != null)
.Select(x => x.IdFile)
.OrderByDescending(x => x)
.ToList();
FileInfoDto actualFile = null;
if (fileIds.Any())
{
var actualFileId = fileIds.FirstOrDefault();
actualFile = fileService.GetInfoAsync(actualFileId ?? default(int), token).Result;
}
// Формирование модели дела
result.Add(new WellFinalDocumentsDto {
IdWell = idWell,
NameCategory = item.NameCategory,
ListResponsible = allUsers.Where(x => userIds.Contains(x.Id)),
CountFiles = fileIds.Count(x => x.HasValue),
File = actualFile
});
});
}
return result;
}
public async Task> GetListResponsiblesAsync(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 SaveCategoryFile(int idDto, Stream fileStream, string fileName, CancellationToken token)
{
// Получаем запись
var dtos = await context.WellFinalDocuments.Where(x => x.Id == idDto)
.Select(x => new WellFinalDocumentsDBDto
{
Id = x.Id,
IdCategory = x.IdCategory,
IdWell = x.IdWell,
IdUser = x.IdUser,
IdFile = x.IdFile
})
.ToListAsync(token)
.ConfigureAwait(false);
var dto = dtos.FirstOrDefault();
// Сохраняем файл и добавляем id файла в запись
var file = await fileService.SaveAsync(dto.IdWell, dto.IdUser, dto.IdCategory, fileName,
fileStream, token).ConfigureAwait(false);
if (file != null)
dto.IdFile = file.Id;
var data = await base.UpdateAsync(dto, token);
return data;
}
public async Task GetHistoryFileByIdCategory(int idWell, int idCategory, CancellationToken token)
{
// Выбиираем все id файлов, по id скважины и id категории
var wellsIds = await context.WellFinalDocuments
.Where(x => idWell == x.IdWell && x.IdCategory == idCategory && x.IdFile != null)
.Select(x => (int)x.IdFile)
.ToListAsync(token)
.ConfigureAwait(false);
// Находим фалы
var files = await fileService.GetInfoByIdsAsync(wellsIds, token).ConfigureAwait(false);
return new WellFinalDocumentsHistoryDto {
IdWell = idWell,
IdCategory = idCategory,
File = files
};
}
private async Task GenerateMessage(List 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)
{
var currentUser = users.FirstOrDefault(x => x.Id == item.IdUser);
var categoryName = category.FirstOrDefault(x => x.Id == item.IdCategory)?.Name;
await SendMessage(item.IdWell, currentUser, categoryName, message, token);
}
}
private async Task SendMessage(int idWell, UserDto user, string documentCategory, string message, CancellationToken token)
{
var well = await wellService.GetOrDefaultAsync(idWell, token);
var factory = new MailBodyFactory(configuration);
var subject = MailBodyFactory.MakeSubject(well, string.Format(message, documentCategory));
var body = factory.MakeMailBodyForNewPublisher(well, user.Name, documentCategory);
emailService.EnqueueSend(user.Email, subject, body);
}
private static WellFinalDocumentsDBDto Convert(WellFinalDocuments dto)
=> new WellFinalDocumentsDBDto
{
Id = dto.Id,
IdCategory = dto.IdCategory,
IdWell = dto.IdWell,
IdUser = dto.IdUser,
IdFile = dto.IdFile
};
}
}