Backend/e-suite.Modules.SpecificationManager/e-suite.Modules.SpecificationManager/SpecificationManager.cs

238 lines
9.7 KiB
C#

using e_suite.Database.Audit;
using e_suite.Database.Core.Tables.Printer;
using e_suite.Utilities.Pagination;
using eSuite.Core.Miscellaneous;
using System.Linq.Expressions;
using e_suite.API.Common;
using e_suite.API.Common.exceptions;
using e_suite.API.Common.models;
using e_suite.API.Common.repository;
using e_suite.Database.Core.Extensions;
using e_suite.Database.Core.Models;
using e_suite.Messaging.Common;
namespace e_suite.Modules.SpecificationManager;
public class SpecificationManager : ISpecificationManager
{
private readonly ISpecificationManagerRepository _specificationManagerRepository;
private readonly IGlossariesManagerRepository _glossariesManagerRepository;
private readonly IFormRepository _formRepository;
private readonly ISiteManagerRepository _siteManagerRepository;
private readonly IEFlowSyncMessageSender _eFlowSyncMessageSender;
#pragma warning disable IDE0290
public SpecificationManager(ISpecificationManagerRepository specificationManagerRepository, IGlossariesManagerRepository glossariesManagerRepository, IFormRepository formRepository, ISiteManagerRepository siteManagerRepository, IEFlowSyncMessageSender eFlowSyncMessageSender)
{
_specificationManagerRepository = specificationManagerRepository;
_glossariesManagerRepository = glossariesManagerRepository;
_formRepository = formRepository;
_siteManagerRepository = siteManagerRepository;
_eFlowSyncMessageSender = eFlowSyncMessageSender;
}
#pragma warning restore IDE0290
private static void Assert<T>(T? item, string message)
{
if (typeof(T).IsAssignableTo(typeof(ISoftDeletable)))
{
if (item is not ISoftDeletable deletable || deletable.Deleted)
throw new NotFoundException(message);
}
else
{
if (item == null)
throw new NotFoundException(message);
}
}
public async Task<GeneralIdRef?> GetTemplateForPrintSpec(GeneralIdRef generalIdRef, CancellationToken cancellationToken)
{
var printSpecificationTemplateGuid = new Guid("{8D910089-3079-4A29-ABAD-8DDF82DB6DBB}");
var printSpecification = await _glossariesManagerRepository.FindGlossary(generalIdRef, cancellationToken);
Assert(printSpecification, "Template glossary item does not exist");
var customFieldValue = printSpecification!.CustomFieldValues.SingleOrDefault(x => x.CustomField.Guid == printSpecificationTemplateGuid);
Assert(customFieldValue, "Glossary does not contain template reference");
var specificationFormGuid = customFieldValue!.Value;
var specificationFormGeneralIdRef = new GeneralIdRef { Guid = new Guid(specificationFormGuid) };
var result = await _formRepository.GetTemplateAsync(specificationFormGeneralIdRef,cancellationToken);
Assert(result, "Template does not exist");
return result.ToGeneralIdRef();
}
public async Task<ReadSpecification?> GetSpecification(GeneralIdRef generalIdRef, CancellationToken cancellationToken)
{
var specification = await _specificationManagerRepository.GetSpecification(generalIdRef, cancellationToken);
Assert(specification, "Specification not found");
return await MapSpecification(specification!, cancellationToken);
}
private readonly Dictionary<GeneralIdRef, Site> _siteDictionary = [];
public async Task CreateSpecification(
AuditUserDetails auditUserDetails,
CreateSpecification create,
bool triggerEFlowSync,
CancellationToken cancellationToken
)
{
await CreateSpecification(auditUserDetails, [create], triggerEFlowSync, cancellationToken);
}
public async Task CreateSpecification(
AuditUserDetails auditUserDetails,
IEnumerable<CreateSpecification> items,
bool triggerEFlowSync,
CancellationToken cancellationToken
)
{
var newSpecifications = new List<Specification>();
foreach (var create in items)
{
if (!_siteDictionary.TryGetValue(create.Site, out var site))
{
site = await _siteManagerRepository.GetSite(create.Site, cancellationToken) ??
throw new NotFoundException("Site not found");
_siteDictionary.Add(create.Site, site);
}
var formInstance = await _formRepository.GetFormInstance(create.FormInstanceId, false, cancellationToken) ??
throw new NotFoundException("Form instance not found");
var newSpecification = new Specification
{
Guid = create.Guid ?? Guid.NewGuid(),
Name = create.Name,
FormInstanceId = formInstance.Id,
Site = site,
SiteId = site.Id,
SigmaId = create.SigmaId
};
newSpecifications.Add(newSpecification);
}
await _specificationManagerRepository.TransactionAsync(async () =>
{
await _specificationManagerRepository.CreateSpecification(auditUserDetails, newSpecifications, cancellationToken);
});
if (triggerEFlowSync)
_eFlowSyncMessageSender.SyncEFlowPrinterCategories();
}
public async Task<IPaginatedData<ReadSpecification>> GetSpecifications(Paging paging, CancellationToken cancellationToken)
{
var specifications = _specificationManagerRepository.GetSpecifications();
var paginatedData = await PaginatedData.Paginate(specifications, paging,
KeySelector, cancellationToken);
var dataPage = new List<ReadSpecification>();
foreach (var data in paginatedData.Data)
dataPage.Add(await MapSpecification(data, cancellationToken));
var paginatedResult = new PaginatedData<ReadSpecification>
{
Count = paginatedData.Count,
Page = paginatedData.Page,
PageSize = paginatedData.PageSize,
Data = dataPage
};
return paginatedResult;
}
private async Task<ReadSpecification> MapSpecification(Specification specification, CancellationToken cancellationToken)
{
var formInstanceId = specification.FormInstanceId;
var formInstance = await _formRepository.GetFormInstance(new GeneralIdRef { Id = formInstanceId }, false, cancellationToken) ??
throw new NotFoundException("Form instance not found");
return new ReadSpecification
{
Id = specification.Id,
Guid = specification.Guid,
Name = specification.Name,
Site = specification.Site.ToGeneralIdRef()!,
SigmaId = specification.SigmaId,
FormInstanceId = formInstance.ToGeneralIdRef()!,
};
}
private Expression<Func<Specification, object>> KeySelector(string? sortKey)
{
return sortKey?.ToLowerInvariant() switch
{
"id" => x => x.Id,
"guid" => x => x.Guid,
"name" => x => x.Name,
"site.id" => x => x.Site.Id,
_ => x => x.Name
};
}
public async Task DeleteSpecification(
AuditUserDetails auditUserDetails,
GeneralIdRef generalIdRef,
bool triggerEFlowSync,
CancellationToken cancellationToken
)
{
await _specificationManagerRepository.TransactionAsync(async () =>
{
var specification = await _specificationManagerRepository.GetSpecification(generalIdRef, cancellationToken);
Assert(specification, "Specification not found");
specification!.Deleted = true;
await _specificationManagerRepository.EditSpecification(auditUserDetails, specification, cancellationToken);
if (triggerEFlowSync)
_eFlowSyncMessageSender.SyncEFlowPrinterCategories();
});
}
public async Task EditSpecification(AuditUserDetails auditUserDetails, EditSpecification edit, bool triggerEFlowSync, CancellationToken cancellationToken)
{
await EditSpecification(auditUserDetails, [edit], triggerEFlowSync, cancellationToken);
}
public async Task EditSpecification(AuditUserDetails auditUserDetails, IEnumerable<EditSpecification> items, bool triggerEFlowSync, CancellationToken cancellationToken)
{
await _specificationManagerRepository.TransactionAsync(async () =>
{
var updates = new List<Specification>();
foreach (var edit in items)
{
var specification =
await _specificationManagerRepository.GetSpecification(edit.Id, cancellationToken) ??
throw new NotFoundException("Specification not found");
var formInstance = await _formRepository.GetFormInstance(edit.FormInstanceId, false, cancellationToken) ??
throw new NotFoundException("Form instance not found");
specification.Name = edit.Name;
specification.FormInstanceId = formInstance.Id;
if (!specification.Site.GeneralIdEquals(edit.Site))
{
var site = await _siteManagerRepository.GetSite(edit.Site, cancellationToken) ??
throw new NotFoundException("Site not found");
specification.Site = site;
specification.SiteId = site.Id;
}
//todo sort out the domain delta changes here.
updates.Add(specification);
}
await _specificationManagerRepository.EditSpecification(auditUserDetails, updates, cancellationToken);
if (triggerEFlowSync)
_eFlowSyncMessageSender.SyncEFlowPrinterCategories();
});
}
}