245 lines
10 KiB
C#
245 lines
10 KiB
C#
using e_suite.API.Common;
|
|
using e_suite.API.Common.exceptions;
|
|
using e_suite.API.Common.repository;
|
|
using e_suite.Database.Audit;
|
|
using e_suite.Database.Core.Extensions;
|
|
using e_suite.Modules.WorkflowTemplatesManager.Repository;
|
|
using e_suite.Utilities.Pagination;
|
|
using e_suite.Workflow.Core.Attributes;
|
|
using e_suite.Workflow.Core.Extensions;
|
|
using e_suite.Workflow.Core.Interfaces;
|
|
using eSuite.Core.Miscellaneous;
|
|
using System.Linq.Expressions;
|
|
using System.Reflection;
|
|
using e_suite.Database.Core.Tables.Workflow;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
|
|
//using WorkflowVersion = e_suite.Workflow.Core.WorkflowVersion;
|
|
|
|
namespace e_suite.Modules.WorkflowTemplatesManager;
|
|
|
|
public class WorkflowTemplateManager : IWorkflowTemplateManager
|
|
{
|
|
private readonly IWorkflowTemplateRepository _workflowTemplateRepository;
|
|
private readonly IWorkflowConverter _workflowConverter;
|
|
private readonly IDomainRepository _domainRepository;
|
|
private readonly IPatchFactory _patchFactory;
|
|
|
|
public WorkflowTemplateManager(IWorkflowTemplateRepository workflowTemplateRepository, IPatchFactory patchFactory, IDomainRepository domainRepository, IWorkflowConverter workflowConverter)
|
|
{
|
|
_workflowTemplateRepository = workflowTemplateRepository;
|
|
_patchFactory = patchFactory;
|
|
_domainRepository = domainRepository;
|
|
_workflowConverter = workflowConverter;
|
|
}
|
|
|
|
public async Task<PaginatedData<GetWorkflowTemplate>> GetWorkflowTemplatesAsync(Paging paging, CancellationToken cancellationToken)
|
|
{
|
|
var ssoProviders = _workflowTemplateRepository.GetWorkflows().Where(x => x.Deleted == false);
|
|
|
|
var paginatedData = await PaginatedData.Paginate<e_suite.Database.Core.Tables.Workflow.Workflow, GetWorkflowTemplate>(ssoProviders, paging,
|
|
WorkflowKeySelector, cancellationToken);
|
|
|
|
return paginatedData;
|
|
}
|
|
|
|
private Expression<Func<e_suite.Database.Core.Tables.Workflow.Workflow, object>> WorkflowKeySelector(string sortKey)
|
|
{
|
|
return sortKey?.ToLowerInvariant() switch
|
|
{
|
|
"id" => x => x.Id,
|
|
"guid" => x => x.Guid,
|
|
"name" => x => x.Name,
|
|
"lastupdated" => x => x.LastUpdated,
|
|
_ => x => x.Id
|
|
};
|
|
}
|
|
|
|
public async Task<PaginatedData<GetWorkflowTemplateVersion>> GetWorkflowTemplateVersionsAsync(Paging paging, CancellationToken cancellationToken)
|
|
{
|
|
var ssoProviders = _workflowTemplateRepository.GetWorkflowVersions().Where(x => x.Deleted == false);
|
|
|
|
var paginatedData = await PaginatedData.Paginate<e_suite.Database.Core.Tables.Workflow.WorkflowVersion, GetWorkflowTemplateVersion>(ssoProviders, paging,
|
|
KeySelector, cancellationToken);
|
|
|
|
return paginatedData;
|
|
}
|
|
|
|
private Expression<Func<e_suite.Database.Core.Tables.Workflow.WorkflowVersion, object>> KeySelector(string sortKey)
|
|
{
|
|
return sortKey?.ToLowerInvariant() switch
|
|
{
|
|
"id" => x => x.Id,
|
|
"activitynametemplate" => x => x.ActivityNameTemplate,
|
|
"description" => x => x.Description,
|
|
"domain.name" => x => x.Domain.Name,
|
|
"workflow.name" => x => x.Workflow.Name,
|
|
_ => x => x.Id
|
|
};
|
|
}
|
|
|
|
public async Task<GetWorkflowTemplateVersion?> GetWorkflowTemplateAsync(GeneralIdRef generalIdRef, CancellationToken cancellationToken)
|
|
{
|
|
var workflow = await _workflowTemplateRepository.GetWorkflows().FindByGeneralIdRefAsync(generalIdRef, cancellationToken) ?? throw new NotFoundException("Unable to find Workflow");
|
|
|
|
var dbWorkflowTemplate = _workflowTemplateRepository.GetWorkflowVersions().Where(x => x.WorkflowId == workflow.Id).OrderByDescending( x => x.Version).First();
|
|
//var dbWorkflowTemplate = await _workflowTemplateRepository.GetWorkflowVersions().FindByGeneralIdRefAsync(generalIdRef, cancellationToken) ?? throw new NotFoundException("Unable to find Workflow Version");
|
|
|
|
//var workflowTemplate = _workflowConverter.DeserialiseFromDatabase(dbWorkflowTemplate);
|
|
|
|
return new GetWorkflowTemplateVersion(dbWorkflowTemplate);
|
|
}
|
|
|
|
public async Task EditTemplateVersion(
|
|
AuditUserDetails auditUserDetails,
|
|
EditWorkflowTemplateVersion template,
|
|
CancellationToken cancellationToken
|
|
)
|
|
{
|
|
await AlterWorkflowTemplateVersionAsync(auditUserDetails, template.ToGeneralIdRef()!, async version =>
|
|
{
|
|
var domain = await _domainRepository.GetDomainById(template.DomainId!, cancellationToken) ?? throw new NotFoundException("Unable to find Domain with provided id");
|
|
|
|
version.Domain = domain;
|
|
version.DomainId = domain.Id;
|
|
version.Description = template.Description;
|
|
version.ActivityNameTemplate = template.ActivityNameTemplate;
|
|
version.Deleted = false;
|
|
version.Version = template.Version+1;
|
|
version.Tasks = template.Tasks;
|
|
}, cancellationToken);
|
|
}
|
|
|
|
public async Task PatchTemplateVersion(
|
|
AuditUserDetails auditUserDetails,
|
|
IGeneralIdRef templateId,
|
|
PatchWorkflowTemplateVersion patchTemplate,
|
|
CancellationToken cancellationToken
|
|
)
|
|
{
|
|
var patch = _patchFactory.Create(patchTemplate);
|
|
await AlterWorkflowTemplateVersionAsync(auditUserDetails, templateId, async version =>
|
|
{
|
|
await patch.ApplyTo(version);
|
|
}, cancellationToken);
|
|
}
|
|
|
|
public async Task PostTemplateVersion(
|
|
AuditUserDetails auditUserDetails,
|
|
CreateWorkflowTemplateVersion template,
|
|
CancellationToken cancellationToken
|
|
)
|
|
{
|
|
await _workflowTemplateRepository.TransactionAsync(async () =>
|
|
{
|
|
if (_workflowTemplateRepository.GetWorkflows().FirstOrDefault(x => x.Name == template.WorkflowName) !=
|
|
null)
|
|
{
|
|
throw new ExistsException("Workflow already exists");
|
|
}
|
|
|
|
var workflow = new Database.Core.Tables.Workflow.Workflow
|
|
{
|
|
Name = template.WorkflowName,
|
|
Guid = Guid.NewGuid()
|
|
};
|
|
|
|
await _workflowTemplateRepository.AddWorkflow(auditUserDetails, workflow, cancellationToken);
|
|
|
|
var workflowDomain = await _domainRepository.GetDomainById(template.DomainId, cancellationToken) ?? throw new NotFoundException("Unable to find domain");
|
|
|
|
var dbWorkflowTemplate = new WorkflowVersion
|
|
{
|
|
Guid = Guid.NewGuid(),
|
|
ActivityNameTemplate = template.ActivityNameTemplate,
|
|
Description = template.Description,
|
|
Domain = workflowDomain,
|
|
Tasks = template.Tasks,
|
|
Workflow = workflow,
|
|
Version = 1
|
|
};
|
|
|
|
//This will attempt to parse the data onto the internal workflow structure.
|
|
//Workflow.Core.WorkflowVersion? workflowTemplate = _workflowConverter.DeserialiseFromDatabase(dbWorkflowTemplate);
|
|
//if (workflowTemplate is null)
|
|
//{
|
|
// throw new InvalidDataException("The workflow template is not valid");
|
|
//}
|
|
|
|
await _workflowTemplateRepository.AddWorkflowVersion(auditUserDetails, dbWorkflowTemplate, cancellationToken);
|
|
|
|
|
|
}
|
|
);
|
|
}
|
|
|
|
public async Task DeleteTemplateVersion(AuditUserDetails auditUserDetails, IGeneralIdRef templateId, CancellationToken cancellationToken)
|
|
{
|
|
await AlterWorkflowTemplateVersionAsync(auditUserDetails, templateId, async version =>
|
|
{
|
|
version.Deleted = true;
|
|
}, cancellationToken);
|
|
}
|
|
|
|
private async Task AlterWorkflowTemplateVersionAsync(
|
|
AuditUserDetails auditUserDetails,
|
|
IGeneralIdRef generalIdRef,
|
|
Func<e_suite.Database.Core.Tables.Workflow.WorkflowVersion, Task> applyChanges,
|
|
CancellationToken cancellationToken
|
|
)
|
|
{
|
|
await _workflowTemplateRepository.TransactionAsync(async () =>
|
|
{
|
|
var workflowVersion = await _workflowTemplateRepository.GetWorkflowVersions().FindByGeneralIdRefAsync(generalIdRef, cancellationToken) ?? throw new NotFoundException("SsoProvider with this id does not exists");
|
|
|
|
await applyChanges(workflowVersion);
|
|
|
|
await _workflowTemplateRepository.EditWorkflowVersionAsync(auditUserDetails, workflowVersion, cancellationToken);
|
|
});
|
|
}
|
|
|
|
private static string FormatInterfaceName(Type interfaceType)
|
|
{
|
|
if (!interfaceType.IsGenericType)
|
|
return interfaceType.Name;
|
|
|
|
var genericName = interfaceType.Name;
|
|
var tickIndex = genericName.IndexOf('`');
|
|
if (tickIndex > 0)
|
|
genericName = genericName.Substring(0, tickIndex);
|
|
|
|
var genericArgs = interfaceType.GetGenericArguments();
|
|
var formattedArgs = string.Join(", ", genericArgs.Select(a => a.Name));
|
|
|
|
return $"{genericName}<{formattedArgs}>";
|
|
}
|
|
|
|
public Task<List<TaskMetadata>> GetAllowedTaskMetadataList(string? taskType, CancellationToken cancellationToken)
|
|
{
|
|
var taskTypeAttribute = StageExtensions.GetTaskAttributeType(taskType);
|
|
|
|
var allowedTypes = StageExtensions.GetAllowedTaskTypes(taskTypeAttribute);
|
|
|
|
var result = allowedTypes
|
|
.Select(t =>
|
|
{
|
|
var interfaces = t.GetInterfaces();
|
|
var capabilities = interfaces
|
|
.Where(i => i.GetCustomAttribute<TaskCapabilityAttribute>() != null)
|
|
.Select(FormatInterfaceName)
|
|
.ToList();
|
|
|
|
var newTaskMetadata = new TaskMetadata
|
|
{
|
|
TaskType = t.FullName!,
|
|
DisplayName = t.Name,
|
|
};
|
|
newTaskMetadata.Capabilities.AddRange(capabilities);
|
|
|
|
return newTaskMetadata;
|
|
})
|
|
.ToList();
|
|
|
|
return Task.FromResult(result);
|
|
}
|
|
} |