Files
adas-core/adas-core.Application/Services/DisplayConfigService.cs

608 lines
26 KiB
C#

using adas_core.Application.Exceptions;
using adas_core.Application.Repositories.Interfaces;
using adas_core.Application.Services.Interfaces;
using adas_core.Application.Subscriptions;
using adas_core.Domain.Enums;
using adas_core.Domain.Models.DTO.Display;
using adas_core.Domain.Models.Filter;
using adas_core.Domain.Models.GroupedObservations;
using adas_core.Domain.Models.MongoModels;
using adas_core.Domain.Models.Responses;
using adas_core.Domain.Utils;
using Microsoft.AspNetCore.Http;
using MongoDB.Bson;
using MongoDB.Driver;
using Newtonsoft.Json;
using Serilog;
using DisplayConfig = adas_core.Domain.Models.MongoModels.DisplayConfig;
namespace adas_core.Application.Services;
public class DisplayConfigService(
IDisplayConfigRepository displayConfigRepository,
Lazy<IDisplayService> displayService,
ISubscribersService subscribersService,
IClientMessageService clientMessageService,
IHttpContextAccessor httpContextAccessor,
ILocalAuditService auditService,
IMasterListServiceFactory masterListServiceFactory,
IDisplayCardConfigRepository displayCardConfigRepository,
IDisplayDetailConfigRepository displayDetailConfigRepository,
IDisplayChartConfigRepository displayChartRepository)
: IDisplayConfigService
{
public async Task<List<DisplayConfig>> GetAll()
{
var result = await displayConfigRepository.GetAll();
var resultToReturn = new List<DisplayConfig>();
foreach (var config in result)
{
var c = await AddDisplaySectionMinimal(config);
if (c != null) resultToReturn.Add(c);
}
return resultToReturn;
}
public async Task<PaginationResponse<DisplayConfigMinimalResponse>> GetAllCompactPaginated(PaginationFilter filter)
{
var result = displayConfigRepository.GetAllPaginated(filter);
var count = await result.CountDocumentsAsync();
var resultToReturn = new List<DisplayConfigMinimalResponse>();
var data = await result.Skip((filter.PageNumber - 1) * filter.PageSize)
.Limit(filter.PageSize)
.ToCursorAsync();
var dataList = await data.ToListAsync();
foreach (var config in dataList)
{
var isInUse = await displayService.Value.IsDisplayConfigInUse(config.Id);
resultToReturn.Add(new DisplayConfigMinimalResponse(config, isInUse));
}
return new PaginationResponse<DisplayConfigMinimalResponse>(resultToReturn, filter.PageNumber, filter.PageSize,
count);
}
public async Task<List<DisplayConfig>> GetByType(DisplayConfigEnums.DisplayType type)
{
var result = await displayConfigRepository.GetByType(type);
var resultToReturn = new List<DisplayConfig>();
foreach (var config in result)
{
var c = await AddDisplaySectionMinimal(config);
if (c != null) resultToReturn.Add(c);
}
return resultToReturn;
}
public async Task<DisplayConfig> GetById(ObjectId id)
{
return await AddDisplaySectionMinimal(await displayConfigRepository.GetById(id)) ??
throw new NotFoundException(HttpEnum.ErrorMessage.NotFoundResourceMissing);
}
public async Task<DisplayConfig?> GetById(ObjectId? configId, ObjectId unitId,
DisplayConfigEnums.DisplayType displayType)
{
if (configId.HasValue)
{
DisplayConfig? currentConfig;
DisplayConfig? defaultConfig;
try
{
currentConfig = await GetById(configId.Value);
}
catch (NotFoundException)
{
currentConfig = null;
}
try
{
defaultConfig = await GetDefaultByUnitIdAndType(unitId, displayType);
}
catch (NotFoundException)
{
defaultConfig = null;
}
if (defaultConfig != null && currentConfig != null) return currentConfig.MergeConfig(defaultConfig);
return defaultConfig ?? currentConfig;
}
return await GetDefaultByUnitIdAndType(unitId, displayType);
}
public async Task<DisplayConfig?> InsertOne(DisplayConfig config)
{
await auditService.CreateAuditLogAsync(httpContextAccessor.HttpContext?.User!, null, config);
return await displayConfigRepository.InsertOneAsyncAndReturn(config);
}
public async Task<DisplayConfig?> InsertOneMinimal(CreateDisplayConfigDto config)
{
DisplayConfig newDisplayConfig;
if (config.Type == DisplayConfigEnums.DisplayType.DisplayNurse)
newDisplayConfig = new DisplayNurse
{
Hospital = config.Hospital,
Type = config.Type
};
else
newDisplayConfig = new DisplayConfig
{
Hospital = config.Hospital,
Type = config.Type
};
newDisplayConfig.Id = ObjectId.GenerateNewId();
var result = await displayConfigRepository.InsertOneAsyncAndReturn(newDisplayConfig);
await auditService.CreateAuditLogAsync(httpContextAccessor.HttpContext?.User!, null, newDisplayConfig);
return result;
}
public async Task<DisplayConfig> InsertOneTest()
{
var d = new DisplayNurse
{
Type = DisplayConfigEnums.DisplayType.DisplayNurse
};
await displayConfigRepository.InsertOneAsyncAndReturn(d);
var e = new SmartDisplay
{
Type = DisplayConfigEnums.DisplayType.SmartDisplay
};
await displayConfigRepository.InsertOneAsyncAndReturn(e);
return d;
}
public async Task<DisplayConfig?> UpdateConfig(ObjectId displayConfigId, object newDisplayConfig)
{
var baseType = JsonConvert.DeserializeObject<DisplayConfigDto>(newDisplayConfig.ToString()!);
// var cardConfigUpdate = await UpdateDisplayCardConfig(displayConfigId, baseType);
var oldDisplayConfig = await displayConfigRepository.GetById(displayConfigId);
switch (baseType!.Type)
{
case DisplayConfigEnums.DisplayType.SmartDisplay:
var smartConfigToReturn = await displayConfigRepository.UpdateSmartDisplay(displayConfigId,
JsonConvert.DeserializeObject<SmartDisplay>(newDisplayConfig.ToString()!));
if (smartConfigToReturn != null)
{
// smartConfigToReturn.CardConfig = cardConfigUpdate;
SendSmartDisplayConfigBroadcast(displayConfigId, smartConfigToReturn,
oldDisplayConfig as SmartDisplay);
await auditService.CreateAuditLogAsync(httpContextAccessor.HttpContext?.User!, oldDisplayConfig,
newDisplayConfig);
return smartConfigToReturn;
}
break;
case DisplayConfigEnums.DisplayType.DisplayNurse:
var obsNurseList = masterListServiceFactory.StringNurseObs();
var displayConfigUpdate =
JsonConvert.DeserializeObject<DisplayNurseDto>(newDisplayConfig.ToString()!);
var nurseConfigToReturn =
await displayConfigRepository.UpdateDisplayNurse(displayConfigId, displayConfigUpdate,
obsNurseList);
if (nurseConfigToReturn != null)
{
// nurseConfigToReturn.CardConfig = cardConfigUpdate;
SendDisplayConfigBroadcast(displayConfigId, OperationType.UpdateDisplayConfig, nurseConfigToReturn);
await auditService.CreateAuditLogAsync(httpContextAccessor.HttpContext?.User!, oldDisplayConfig,
nurseConfigToReturn);
return nurseConfigToReturn;
}
break;
default:
throw new NotFoundException(HttpEnum.ErrorMessage.NotFoundNoMatches);
}
throw new NotFoundException(HttpEnum.ErrorMessage.NotFoundResourceMissing);
}
public Task<bool> UpdateFieldList(ObjectId objectIdConfigDisplay, List<Field> fields)
{
return displayConfigRepository.UpdateFieldList(objectIdConfigDisplay, fields);
}
public async Task<bool> UpdateConfigColor(ObjectId objectIdConfigDisplay, ColorConfig colorConfig)
{
var oldDisplayConfig = await displayConfigRepository.GetById(objectIdConfigDisplay) ??
throw new NotFoundException(HttpEnum.ErrorMessage.NotFoundResourceMissing);
if (oldDisplayConfig.ColorConfig == null)
{
oldDisplayConfig.ColorConfig = new ColorConfig();
await displayConfigRepository.UpdateOneAsync(objectIdConfigDisplay, oldDisplayConfig);
}
var result = await displayConfigRepository.UpdateConfigColor(objectIdConfigDisplay, colorConfig);
var newDisplayConfig = await displayConfigRepository.GetById(objectIdConfigDisplay) ??
throw new NotFoundException(HttpEnum.ErrorMessage.NotFoundResourceMissing);
await auditService.CreateAuditLogAsync(httpContextAccessor.HttpContext?.User!, oldDisplayConfig,
newDisplayConfig);
return result;
}
public async Task<bool> UpdateHeaderConfig(ObjectId objectIdConfigDisplay, HeaderConfig headerConfig)
{
var oldDisplayConfig = await displayConfigRepository.GetById(objectIdConfigDisplay) ??
throw new NotFoundException(HttpEnum.ErrorMessage.NotFoundResourceMissing);
var result = await displayConfigRepository.UpdateHeaderConfig(objectIdConfigDisplay, headerConfig);
var newDisplayConfig = await displayConfigRepository.GetById(objectIdConfigDisplay) ??
throw new NotFoundException(HttpEnum.ErrorMessage.NotFoundResourceMissing);
await auditService.CreateAuditLogAsync(httpContextAccessor.HttpContext?.User!, oldDisplayConfig,
newDisplayConfig);
return result;
}
public async Task<bool> UpdateSetHomeBanner(ObjectId objectIdConfigDisplay, List<BannerItem> bannerItems)
{
var oldDisplayConfig = await displayConfigRepository.GetById(objectIdConfigDisplay) ??
throw new NotFoundException(HttpEnum.ErrorMessage.NotFoundResourceMissing);
var result = await displayConfigRepository.UpdateSetHomeBanner(objectIdConfigDisplay, bannerItems);
var newDisplayConfig = await displayConfigRepository.GetById(objectIdConfigDisplay) ??
throw new NotFoundException(HttpEnum.ErrorMessage.NotFoundResourceMissing);
await auditService.CreateAuditLogAsync(httpContextAccessor.HttpContext?.User!, oldDisplayConfig,
newDisplayConfig);
return result;
}
public async Task<bool> UpdateBaseConfig(DisplayConfig baseConfig)
{
var oldDisplayConfig = await displayConfigRepository.GetById(baseConfig.Id) ??
throw new NotFoundException(HttpEnum.ErrorMessage.NotFoundResourceMissing);
var result = await displayConfigRepository.UpdateBaseConfig(baseConfig.Id, baseConfig);
var newDisplayConfig = await displayConfigRepository.GetById(baseConfig.Id) ??
throw new NotFoundException(HttpEnum.ErrorMessage.NotFoundResourceMissing);
await auditService.CreateAuditLogAsync(httpContextAccessor.HttpContext?.User!, oldDisplayConfig,
newDisplayConfig);
return result;
}
public async Task<bool> UpdateDisplayConfigHospitalName(ObjectId objectIdConfigDisplay, string name)
{
var oldDisplayConfig = await displayConfigRepository.GetById(objectIdConfigDisplay) ??
throw new NotFoundException(HttpEnum.ErrorMessage.NotFoundResourceMissing);
var result = await displayConfigRepository.UpdateDisplayConfigHospitalName(objectIdConfigDisplay, name);
var newDisplayConfig = await displayConfigRepository.GetById(objectIdConfigDisplay) ??
throw new NotFoundException(HttpEnum.ErrorMessage.NotFoundResourceMissing);
await auditService.CreateAuditLogAsync(httpContextAccessor.HttpContext?.User!, oldDisplayConfig,
newDisplayConfig);
return result;
}
public async Task<bool> DeleteDisplayConfig(ObjectId objectIdConfigDisplay)
{
var displays = await displayService.Value.GetByConfigId(objectIdConfigDisplay);
if (displays.Count > 0)
{
var type = displays.First().Type;
var defaultConfig = await GetDefaultConfig(type) ??
throw new ConflictException(HttpEnum.ErrorMessage.ConflictDeleteFailed);
foreach (var display in displays)
_ = await displayService.Value.UpdateConfigId(display, defaultConfig.Id) ??
throw new ConflictException(HttpEnum.ErrorMessage.ConflictDeleteFailed);
}
var result = await displayConfigRepository.DeleteDisplayConfig(objectIdConfigDisplay);
if (result != null)
{
await auditService.CreateAuditLogAsync(httpContextAccessor.HttpContext?.User!, result, null);
return true;
}
return false;
}
public async Task<List<DisplayConfigLocationDto>> GetDisplayConfigLocations(ObjectId objectIdConfigDisplay)
{
return await displayService.Value.GetDisplayConfigLocations(objectIdConfigDisplay);
}
public async Task<List<DisplayConfigMinimalResponse>> GetAllCompact()
{
return await displayConfigRepository.GetAllCompact();
}
public async Task<DisplayConfig?> InsertOneWithTemplate(string objectId,
DisplayConfigEnums.DisplayType configType, string? configHospital)
{
if (ObjectId.TryParse(objectId, out var objectIdConfigDisplay))
{
var template = await GetById(objectIdConfigDisplay);
switch (configType)
{
case DisplayConfigEnums.DisplayType.StandarDisplay:
if (template is StandarDisplay standardTemplate)
{
var standarConfigg = new StandarDisplay
{ Hospital = configHospital, Type = DisplayConfigEnums.DisplayType.StandarDisplay };
standarConfigg.MergeConfig(standardTemplate);
await InsertOne(standarConfigg);
return standarConfigg;
}
break;
case DisplayConfigEnums.DisplayType.DisplayNurse:
if (template is DisplayNurse nurseTemplate)
{
var nurseConfig = new DisplayNurse
{ Hospital = configHospital, Type = DisplayConfigEnums.DisplayType.DisplayNurse };
nurseConfig.MergeConfig(nurseTemplate);
await InsertOne(nurseConfig);
return nurseConfig;
}
break;
case DisplayConfigEnums.DisplayType.SmartDisplay:
if (template is SmartDisplay smartTemplate)
{
var smartConfig = new SmartDisplay
{ Hospital = configHospital, Type = DisplayConfigEnums.DisplayType.DisplayNurse };
smartConfig.MergeConfig(smartTemplate);
await InsertOne(smartConfig);
return smartConfig;
}
break;
default:
return null;
}
}
return null;
}
public async Task<bool> UpdateCardConfig(CardConfig baseConfig)
{
var result = await displayCardConfigRepository.UpdateOne(baseConfig);
if (result.Changes > 0)
{
var displayConfigs = await displayConfigRepository.GetAllByCardConfigIdAndRotating(baseConfig.Id);
foreach (var displayConfig in displayConfigs)
{
await displayConfigRepository.UpdateDisplayNurse(displayConfig,
new DisplayNurseDto() { CardConfig = result.Data }, masterListServiceFactory.StringNurseObs());
}
var displays = await displayConfigRepository.GetAllByCardConfigId(baseConfig.Id);
foreach (var display in displays)
SendDisplayConfigBroadcast(display, OperationType.UpdateCardDisplayConfig, result.Data);
return true;
}
return false;
}
public async Task<bool> UpdateDetailConfig(CardDetailsConfig baseConfig)
{
var result = await displayDetailConfigRepository.UpdateOne(baseConfig);
var displays = await displayConfigRepository.GetAllByCardDetailConfigId(baseConfig.Id);
foreach (var display in displays)
SendDisplayConfigBroadcast(display, OperationType.UpdateDetailDisplayConfig, result.Data);
if (result.Changes > 0) return true;
return false;
}
public async Task<bool> UpdateChartConfig(ChartConfig baseConfig)
{
var result = await displayChartRepository.UpdateOne(baseConfig);
if (result.Changes > 0) return true;
return false;
}
public async Task<bool> DeleteChartConfig(ObjectId objectIdConfigDisplay)
{
var res = await displayChartRepository.DeleteOne(objectIdConfigDisplay);
if (res != null)
{
await UpdateDeletedChartConfig(objectIdConfigDisplay);
return true;
}
return false;
}
public async Task<ChartConfig?> GetChartConfig(ObjectId objectIdConfigChart)
{
return await displayChartRepository.GetById(objectIdConfigChart);
}
public async Task<CardDetailsConfig?> InsertCardDetailConfig(CreateDisplayConfigCardDto updateDisplayConfigNameDto)
{
if (updateDisplayConfigNameDto.DetailConfig == null) return null;
var result =
await displayDetailConfigRepository.InsertOneAsyncAndReturn(updateDisplayConfigNameDto.DetailConfig);
if (updateDisplayConfigNameDto.DisplayConfigId != null && result != null)
{
var res = await UpdateDetailConfigId(updateDisplayConfigNameDto.DisplayConfigId, result.Id);
if (res)
SendDisplayConfigBroadcast(updateDisplayConfigNameDto.DisplayConfigId.Value,
OperationType.UpdateDetailDisplayConfig, result);
}
return result;
}
public async Task<ChartConfig?> InsertChartConfig(CreateDisplayConfigCardDto updateDisplayConfigNameDto)
{
if (updateDisplayConfigNameDto.ChartConfig == null) return null;
var result = await displayChartRepository.InsertOneAsyncAndReturn(updateDisplayConfigNameDto.ChartConfig);
if (updateDisplayConfigNameDto.DisplayConfigId != null && result != null)
{
var res = await AddChartId(updateDisplayConfigNameDto.DisplayConfigId, result.Id);
if (res)
SendDisplayConfigBroadcast(updateDisplayConfigNameDto.DisplayConfigId.Value,
OperationType.UpdateChartConfig, result);
}
return result;
}
public async Task<CardConfig?> InsertCardConfig(CreateDisplayConfigCardDto updateDisplayConfigNameDto)
{
if(updateDisplayConfigNameDto.CardConfig == null) return null;
var result = await displayCardConfigRepository.InsertOneAsyncAndReturn(updateDisplayConfigNameDto.CardConfig);
if (updateDisplayConfigNameDto.DisplayConfigId != null && result != null)
{
var res = await UpdateCardConfigId(updateDisplayConfigNameDto.DisplayConfigId, result.Id);
if (res)
SendDisplayConfigBroadcast(updateDisplayConfigNameDto.DisplayConfigId.Value,
OperationType.UpdateDetailDisplayConfig, result);
}
return result;
}
public async Task<List<CardConfig>> GetCardConfigAll()
{
return await displayCardConfigRepository.GetAll();
}
public async Task<CardConfig?> GetCardConfigById(ObjectId id)
{
return await displayCardConfigRepository.GetById(id);
}
public async Task<DisplayConfig?> GetDefaultConfig(DisplayConfigEnums.DisplayType type)
{
return await displayConfigRepository.GetDefault(type);
}
private async Task<DisplayConfig?> GetDefaultByUnitIdAndType(ObjectId unitId,
DisplayConfigEnums.DisplayType displayType)
{
return
await displayConfigRepository.GetDefaultByUnitIdAndType(unitId,
displayType); //?? throw new NotFoundException(ErrorMessage.NotFound_ResourceMissing);
}
private async Task<DisplayConfig?> AddDisplaySectionMinimal(DisplayConfig? displayConfig)
{
if (displayConfig == null) return null;
var displayConfigAux = displayConfigRepository.GetById(displayConfig.Id) ??
throw new NotFoundException(HttpEnum.ErrorMessage.NotFoundResourceMissing);
if (displayConfig.Type == DisplayConfigEnums.DisplayType.SmartDisplay &&
!displayConfig.DisplaySectionIdList.IsNullOrEmpty())
{
foreach (var displayId in displayConfig.DisplaySectionIdList)
{
var d = await displayService.Value.GetById(displayId);
if (d != null)
{
var minimalDisplay = new MinimalDisplaySection
{
Id = displayId,
Name = d.Name
};
displayConfig.DisplaySectionList.Add(minimalDisplay);
}
}
await auditService.CreateAuditLogAsync(httpContextAccessor.HttpContext?.User!, displayConfigAux,
displayConfig);
}
return displayConfig;
}
private async Task UpdateDeletedChartConfig(ObjectId deletedId)
{
await displayConfigRepository.UpdateDeletedChartConfig(deletedId);
}
private async Task<bool> AddChartId(ObjectId? displayConfigId, ObjectId resultId)
{
var result = await displayConfigRepository.AddChartId(displayConfigId, resultId);
return result;
}
private async Task<bool> UpdateCardConfigId(ObjectId? displayConfigId, ObjectId? resultId)
{
var result = await displayConfigRepository.UpdateCardConfigId(displayConfigId, resultId);
return result;
}
private async Task<bool> UpdateDetailConfigId(ObjectId? displayConfigId, ObjectId? resultId)
{
var result = await displayConfigRepository.UpdateDetailConfigId(displayConfigId, resultId);
return result;
}
private async void SendDisplayConfigBroadcast(ObjectId displayConfigId, OperationType operationType,
object? newDisplayConfig)
{
try
{
var listDisplayId = await displayService.Value.GetByConfigId(displayConfigId);
var listDisplayIdList = listDisplayId.Select(c => c.Id).ToList();
var subscribers = subscribersService.GetSubscribers().Where(s =>
s.DisplayId != null && listDisplayIdList.Contains((ObjectId)s.DisplayId)).ToList();
foreach (var sub in subscribers)
_ = clientMessageService.SendAsync(sub.Id, operationType,
newDisplayConfig);
}
catch (Exception e)
{
Log.Error("Error sending update for DisplayNurse config: {message}", e.Message);
//throw new ConflictException(ErrorMessage.Conflict_UpdateFailed, e);
}
}
private async void SendSmartDisplayConfigBroadcast(ObjectId displayConfigId, SmartDisplay? newDisplayConfig,
SmartDisplay? oldDisplayConfig)
{
try
{
var listDisplayId = await displayService.Value.GetByConfigId(displayConfigId);
var listDisplayIdList = listDisplayId.Select(c => c.Id).ToList();
var subscribers = subscribersService.GetSubscribers().Where(s =>
s.DisplayId != null && listDisplayIdList.Contains((ObjectId)s.DisplayId)).ToList();
if (newDisplayConfig != null && oldDisplayConfig != null)
SendSmartDisplayConfigUpdate(subscribers, oldDisplayConfig, newDisplayConfig);
else Log.Error("Error sending update for SmartDisplay config config is null");
}
catch (Exception e)
{
Log.Error("Error sending update for SmartDisplay config: {message}", e.Message);
//throw new ConflictException(ErrorMessage.Conflict_UpdateFailed, e);
}
finally
{
// Enviar un mensaje a todos los clientes para que actualicen la configuracin del display
var displayConfig = await displayConfigRepository.GetById(displayConfigId);
if (displayConfig != null)
_ = clientMessageService.SendToAllAsync(OperationType.UpdateDisplayConfig, displayConfig);
}
}
private void SendSmartDisplayConfigUpdate(List<WsSubscriber> subscribers,
SmartDisplay? oldDisplayDisplayConfig, SmartDisplay? newDisplayDisplayConfig)
{
// Obtener las propiedades que han cambiado
var differentProperties = oldDisplayDisplayConfig?.GetDifferentProperties(newDisplayDisplayConfig);
// Enviar un mensaje a los clientes por cada propiedad que haya cambiado
if (differentProperties != null)
foreach (var property in differentProperties)
foreach (var sub in subscribers)
_ = clientMessageService.SendAsync(sub.Id, OperationType.UpdateDisplayConfig,
newDisplayDisplayConfig?.GetType().GetProperty(property)?.GetValue(newDisplayDisplayConfig));
}
}