using AsbCloudApp.Data;
using AsbCloudApp.Data.User;
using AsbCloudApp.Exceptions;
using AsbCloudApp.Repositories;
using AsbCloudApp.Requests;
using AsbCloudApp.Services;
using Microsoft.Extensions.Configuration;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using AsbCloudApp.Services.Notifications;
using AsbCloudDb.Model;
namespace AsbCloudInfrastructure.Services;
///
/// Сервис "Дело скважины"
///
public class WellFinalDocumentsService : IWellFinalDocumentsService
{
private readonly FileService fileService;
private readonly IUserRepository userRepository;
private readonly IWellService wellService;
private readonly IConfiguration configuration;
private readonly IFileCategoryService fileCategoryService;
private readonly IWellFinalDocumentsRepository wellFinalDocumentsRepository;
private readonly NotificationService notificationService;
public WellFinalDocumentsService(FileService fileService,
IUserRepository userRepository,
IWellService wellService,
IConfiguration configuration,
IFileCategoryService fileCategoryService,
IWellFinalDocumentsRepository wellFinalDocumentsRepository,
NotificationService notificationService)
{
this.fileService = fileService;
this.userRepository = userRepository;
this.wellService = wellService;
this.configuration = configuration;
this.fileCategoryService = fileCategoryService;
this.wellFinalDocumentsRepository = wellFinalDocumentsRepository;
this.notificationService = notificationService;
}
///
public async Task UpdateRangeAsync(int idWell, IEnumerable dtos, CancellationToken token)
{
var data = await wellFinalDocumentsRepository.UpdateRangeAsync(idWell, dtos, token);
var message = "от Вас ожидается загрузка на портал документа «{0}»";
await NotifyUsersAsync(data, message, token);
return data.Count();
}
///
public async Task SaveCategoryFileAsync(int idWell, int idCategory, int idUser, Stream fileStream, string fileName, CancellationToken token)
{
var dto = await wellFinalDocumentsRepository.GetCategoryAsync(idWell, idCategory, idUser, token)
.ConfigureAwait(false);
var file = await fileService.SaveAsync(dto.IdWell, dto.IdUser, dto.IdCategory, fileName,
fileStream, token).ConfigureAwait(false);
return file.Id;
}
///
public async Task GetFilesHistoryByIdCategoryAsync(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,
Files = files
};
}
///
public async Task ReNotifyPublishersAsync(int idWell, int idUser, int idCategory, CancellationToken token)
{
var wellCase = await wellFinalDocumentsRepository.GetByWellIdAsync(idWell, idUser, token);
if (!wellCase.PermissionToSetPubliher)
throw new ForbidException("Повторная отправка оповещений Вам не разрешена");
var requester = await userRepository.GetOrDefaultAsync(idUser, token);
if (requester is null)
throw new ForbidException("Не удается вас опознать");
var docs = wellCase.WellFinalDocuments
.Where(doc => doc.IdCategory == idCategory)
.Where(doc => doc.File is null)
.SelectMany(doc => doc.Publishers
.Select(pub => new WellFinalDocumentDBDto {
IdCategory = idCategory,
IdUser = pub.Id,
IdWell = idWell
}));
if(!docs.Any())
throw new ArgumentInvalidException(nameof(idCategory), "Нет такой категории, или в нее уже загружен документ");
var message = requester.MakeDisplayName() + " ожидает от Вас загрузку на портал документа «{{0}}»";
await NotifyUsersAsync(docs, message, token);
return docs.Count();
}
private async Task NotifyUsersAsync(IEnumerable 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)
?? throw new ArgumentInvalidException(nameof(item.IdWell), "idWell doesn`t exist");
await SendMessageAsync(well, user, category?.Name ?? string.Empty, message,
token);
}
}
}
private async Task SendMessageAsync(WellDto well, UserDto user, string documentCategory, string message,
CancellationToken cancellationToken)
{
const int idTransportType = 1;
var factory = new WellFinalDocumentMailBodyFactory(configuration);
var subject = factory.MakeSubject(well, documentCategory);
var body = factory.MakeMailBodyForWellFinalDocument(
well,
(user.Name ?? user.Surname ?? string.Empty),
string.Format(message, documentCategory)
);
await notificationService.NotifyAsync(new NotifyRequest
{
IdUser = user.Id,
IdNotificationCategory = NotificationCategory.IdSystemNotificationCategory,
Title = subject,
Message = body,
IdTransportType = idTransportType
}, cancellationToken);
}
}