Backend/e-suite.Modules.WorkflowTemplatesManager/Repository/WorkflowTemplateRepository.cs

193 lines
7.3 KiB
C#

using e_suite.API.Common.repository;
using e_suite.Database.Audit;
using e_suite.Database.Core;
using e_suite.Database.Core.Extensions;
using e_suite.Database.Core.Tables.Contacts;
using e_suite.Database.Core.Tables.Domain;
using e_suite.Database.Core.Tables.UserManager;
using e_suite.Workflow.Core;
using e_suite.Workflow.Core.Extensions;
using eSuite.Core.Miscellaneous;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Options;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace e_suite.Modules.WorkflowTemplatesManager.Repository;
public class GeneralIdRefConverter<T> : JsonConverter<T>
{
private readonly Func<GeneralIdRef, T?> _lookup;
public GeneralIdRefConverter(Func<GeneralIdRef, T?> lookup)
{
_lookup = lookup;
}
public override bool CanConvert(Type typeToConvert)
{
// Only convert actual domain types, not enums or primitives
return typeToConvert == typeof(T) &&
!typeToConvert.IsEnum &&
!typeToConvert.IsPrimitive &&
typeToConvert != typeof(string);
}
public override T? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
// Parse the incoming JSON into a GeneralIdRef
using var doc = JsonDocument.ParseValue(ref reader);
var json = doc.RootElement.GetRawText();
var idRef = JsonSerializer.Deserialize<GeneralIdRef>(json, options);
if (idRef == null)
return default;
return _lookup(idRef);
}
public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options)
{
throw new NotImplementedException("Writing not needed.");
}
}
public interface IWorkflowConverter
{
Workflow.Core.WorkflowVersion DeserialiseFromDatabase(e_suite.Database.Core.Tables.Workflow.WorkflowVersion dbVersion);
Task<e_suite.Database.Core.Tables.Workflow.WorkflowVersion> SerialiseToDatabase(
Workflow.Core.WorkflowVersion runtime,
e_suite.Database.Core.Tables.Workflow.WorkflowVersion? dbObject = null,
CancellationToken cancellationToken = default
);
}
public class WorkflowConverter : IWorkflowConverter
{
private readonly IDomainRepository _domainRepository;
private readonly IRoleManagerRepository _roleManagerRepository;
private readonly IUserManagerRepository _userManagerRepository;
private readonly JsonSerializerOptions _jsonSerializerOptions;
public WorkflowConverter(IDomainRepository domainRepository, IRoleManagerRepository roleManagerRepository, IUserManagerRepository userManagerRepository)
{
_domainRepository = domainRepository;
_roleManagerRepository = roleManagerRepository;
_userManagerRepository = userManagerRepository;
_jsonSerializerOptions = new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true
};
_jsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());
_jsonSerializerOptions.Converters.Add(new GeneralIdRefConverter<Role>(id => _roleManagerRepository.GetRoleById(id)));
_jsonSerializerOptions.Converters.Add(new GeneralIdRefConverter<User>(id => _userManagerRepository.GetUserById(id)));
}
public Workflow.Core.WorkflowVersion DeserialiseFromDatabase(e_suite.Database.Core.Tables.Workflow.WorkflowVersion dbVersion)
{
var runtime = new Workflow.Core.WorkflowVersion
{
Id = dbVersion.Id,
Guid = dbVersion.Guid,
Version = dbVersion.Version,
ActivityNameTemplate = dbVersion.ActivityNameTemplate,
Description = dbVersion.Description,
Domain = dbVersion.Domain.ToGeneralIdRef()!,
Template = new WorkflowTemplate
{
Name = "Need to fix",
Id = 1,
Guid = Guid.Empty
} // however you load templates
};
foreach (var def in dbVersion.Tasks)
{
var task = def.ToTask(_jsonSerializerOptions);
runtime.Tasks.Add(task);
}
return runtime;
}
public async Task<e_suite.Database.Core.Tables.Workflow.WorkflowVersion> SerialiseToDatabase(Workflow.Core.WorkflowVersion runtime, e_suite.Database.Core.Tables.Workflow.WorkflowVersion? dbObject = null, CancellationToken cancellationToken = default)
{
if (runtime is null)
throw new NullReferenceException();
var domain = await _domainRepository.GetDomainById(runtime.Domain, cancellationToken);
if (domain is null)
throw new Exception($"Domain with id {runtime.Domain} not found.");
var dbVersion = dbObject ?? new e_suite.Database.Core.Tables.Workflow.WorkflowVersion();
if (dbObject == null)
{
dbVersion.Id = runtime.Id;
dbVersion.Guid = runtime.Guid;
}
else
{
//note cannot move a version from one workflow to another, that requires a new version.
//todo make sure that the Workflow is populated here.
//dbVersion.Workflow = runtime.Template.ToGeneralIdRef()
}
dbVersion.Version = runtime.Version; //todo make sure that the version number get incremented somewhere logical.
dbVersion.ActivityNameTemplate = runtime.ActivityNameTemplate;
dbVersion.Description = runtime.Description;
dbVersion.DomainId = domain.Id;
dbVersion.Tasks = runtime.Tasks
.Select(t => t.ToDefinition())
.ToList();
return dbVersion;
}
}
public class WorkflowTemplateRepository : RepositoryBase, IWorkflowTemplateRepository
{
public WorkflowTemplateRepository(IEsuiteDatabaseDbContext databaseDbContext) : base(databaseDbContext)
{
}
public IQueryable<e_suite.Database.Core.Tables.Workflow.Workflow> GetWorkflows()
{
return DatabaseDbContext.Workflows
.Include( x => x.Versions);
}
public IQueryable<e_suite.Database.Core.Tables.Workflow.WorkflowVersion> GetWorkflowVersions()
{
return DatabaseDbContext.WorkflowVersions
.Include( x => x.Domain)
.Include( x => x.Workflow);
}
public async Task EditWorkflowVersionAsync(AuditUserDetails auditUserDetails, e_suite.Database.Core.Tables.Workflow.WorkflowVersion workflowVersion, CancellationToken cancellationToken)
{
await DatabaseDbContext.SaveChangesAsync(auditUserDetails, cancellationToken);
}
public async Task AddWorkflow(AuditUserDetails auditUserDetails, Database.Core.Tables.Workflow.Workflow workflow, CancellationToken cancellationToken)
{
DatabaseDbContext.Workflows.Add(workflow);
await DatabaseDbContext.SaveChangesAsync(auditUserDetails, cancellationToken);
}
public async Task AddWorkflowVersion(
AuditUserDetails auditUserDetails,
Database.Core.Tables.Workflow.WorkflowVersion workflowVersion,
CancellationToken cancellationToken
)
{
DatabaseDbContext.WorkflowVersions.Add(workflowVersion);
await DatabaseDbContext.SaveChangesAsync(auditUserDetails, cancellationToken);
}
}