Now able to post a workflow template version
This commit is contained in:
parent
e7eaed742e
commit
1d8004ccaa
@ -83,15 +83,13 @@ public class CreateWorkflowTemplateVersion
|
||||
{
|
||||
public List<TaskDefinition> Tasks { get; set; } = [];
|
||||
|
||||
public required GeneralIdRef WorkflowId { get; set; }
|
||||
|
||||
public long Version { get; set; }
|
||||
public required string WorkflowName { get; set; }
|
||||
|
||||
public required GeneralIdRef DomainId { get; set; }
|
||||
|
||||
public string Description { get; set; } = String.Empty;
|
||||
|
||||
public string ActivityNameTemplate { get; set; } = String.Empty;
|
||||
public required string ActivityNameTemplate { get; set; } = String.Empty;
|
||||
}
|
||||
|
||||
public class TaskMetadata
|
||||
|
||||
@ -9,7 +9,8 @@ namespace e_suite.API.Common.repository;
|
||||
public interface IRoleManagerRepository : IRepository
|
||||
{
|
||||
IQueryable<Role> GetRolesList();
|
||||
Task<Role?> GetRoleById(IGeneralIdRef generalIdRef, CancellationToken cancellationToken);
|
||||
Role? GetRoleById(IGeneralIdRef generalIdRef);
|
||||
Task<Role?> GetRoleByIdAsync(IGeneralIdRef generalIdRef, CancellationToken cancellationToken);
|
||||
Task<Role?> GetRoleByName(Domain domain, string sequenceName, CancellationToken cancellationToken);
|
||||
Task EditRole(AuditUserDetails auditUserDetails, Role existingSequence, CancellationToken cancellationToken);
|
||||
Task AddRole(AuditUserDetails auditUserDetails, Role existingSequence, CancellationToken cancellationToken);
|
||||
|
||||
@ -21,7 +21,8 @@ public interface IUserManagerRepository : IRepository
|
||||
Task<EmailUserAction?> GetCurrentEmailUserAction(long userId, EmailUserActionType emailUserActionType, CancellationToken cancellationToken);
|
||||
Task DeleteEmailUserAction(AuditUserDetails auditUserDetails, EmailUserAction emailUserAction, CancellationToken cancellationToken);
|
||||
IQueryable<User> GetUsers();
|
||||
Task<User?> GetUserById(IGeneralIdRef generalIdRef, CancellationToken cancellationToken);
|
||||
User? GetUserById(IGeneralIdRef generalIdRef);
|
||||
Task<User?> GetUserByIdAsync(IGeneralIdRef generalIdRef, CancellationToken cancellationToken);
|
||||
Task<SsoProvider?> GetSsoProviderById(long id, CancellationToken cancellationToken);
|
||||
IQueryable<SsoProvider> GetSsoProviders();
|
||||
Task SaveSingleUseGuidForUser(SingleUseGuid singleUseGuid, CancellationToken cancellationToken);
|
||||
|
||||
@ -9,4 +9,6 @@ public interface IWorkflowTemplateRepository : IRepository
|
||||
public IQueryable<Workflow> GetWorkflows();
|
||||
IQueryable<WorkflowVersion> GetWorkflowVersions();
|
||||
Task EditWorkflowVersionAsync(AuditUserDetails auditUserDetails, WorkflowVersion workflowVersion, CancellationToken cancellationToken);
|
||||
Task AddWorkflow(AuditUserDetails auditUserDetails, Workflow workflow, CancellationToken cancellationToken);
|
||||
Task AddWorkflowVersion(AuditUserDetails auditUserDetails, WorkflowVersion workflowVersion, CancellationToken cancellationToken);
|
||||
}
|
||||
@ -27,7 +27,12 @@ public class FakeRoleManagerRepository : FakeRepository, IRoleManagerRepository
|
||||
return Roles.BuildMock();
|
||||
}
|
||||
|
||||
public Task<Role?> GetRoleById(IGeneralIdRef generalIdRef, CancellationToken cancellationToken)
|
||||
public Role? GetRoleById(IGeneralIdRef generalIdRef)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Task<Role?> GetRoleByIdAsync(IGeneralIdRef generalIdRef, CancellationToken cancellationToken)
|
||||
{
|
||||
return Task.FromResult(GetRolesList().FindByGeneralIdRef(generalIdRef));
|
||||
}
|
||||
|
||||
@ -75,7 +75,12 @@ public class FakeUserManagerRepository : FakeRepository, IUserManagerRepository
|
||||
return Users.BuildMock();
|
||||
}
|
||||
|
||||
public Task<User?> GetUserById(IGeneralIdRef generalIdRef, CancellationToken cancellationToken)
|
||||
public User? GetUserById(IGeneralIdRef generalIdRef)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Task<User?> GetUserByIdAsync(IGeneralIdRef generalIdRef, CancellationToken cancellationToken)
|
||||
{
|
||||
return Task.FromResult(Users.SingleOrDefault(x => x.Id == generalIdRef.Id || x.Guid == generalIdRef.Guid));
|
||||
}
|
||||
|
||||
@ -21,8 +21,14 @@ public class RoleManagerRepository : RepositoryBase, IRoleManagerRepository
|
||||
.Include(nameof(Role.Domain))
|
||||
.Where(x => !x.Deleted);
|
||||
}
|
||||
public Role? GetRoleById(IGeneralIdRef generalIdRef)
|
||||
{
|
||||
return DatabaseDbContext.Roles
|
||||
.Include(nameof(Domain)).AsEnumerable()
|
||||
.FindByGeneralIdRef(generalIdRef);
|
||||
}
|
||||
|
||||
public async Task<Role?> GetRoleById(IGeneralIdRef generalIdRef, CancellationToken cancellationToken)
|
||||
public async Task<Role?> GetRoleByIdAsync(IGeneralIdRef generalIdRef, CancellationToken cancellationToken)
|
||||
{
|
||||
return await DatabaseDbContext.Roles
|
||||
.Include(nameof(Domain))
|
||||
|
||||
@ -86,7 +86,7 @@ public class RoleManager : IRoleManager
|
||||
|
||||
public async Task<ReadRole> GetRole(IGeneralIdRef generalIdRef, CancellationToken cancellationToken)
|
||||
{
|
||||
var role = await _roleManagerRepository.GetRoleById(generalIdRef, cancellationToken) ??
|
||||
var role = await _roleManagerRepository.GetRoleByIdAsync(generalIdRef, cancellationToken) ??
|
||||
throw new NotFoundException("Role not found");
|
||||
|
||||
if (role.Deleted)
|
||||
@ -104,7 +104,7 @@ public class RoleManager : IRoleManager
|
||||
{
|
||||
var existingRole = role.Guid == null
|
||||
? null
|
||||
: await _roleManagerRepository.GetRoleById(new GeneralIdRef
|
||||
: await _roleManagerRepository.GetRoleByIdAsync(new GeneralIdRef
|
||||
{
|
||||
Guid = role.Guid
|
||||
}, cancellationToken);
|
||||
@ -157,7 +157,7 @@ public class RoleManager : IRoleManager
|
||||
throw new InvalidOperationException("GeneralIdRef cannot be null");
|
||||
|
||||
var existingRole =
|
||||
await _roleManagerRepository.GetRoleById(editRole.GeneralIdRef, cancellationToken);
|
||||
await _roleManagerRepository.GetRoleByIdAsync(editRole.GeneralIdRef, cancellationToken);
|
||||
|
||||
if (existingRole == null || existingRole.Deleted)
|
||||
throw new NotFoundException("A role with this Id doesn't exist");
|
||||
@ -179,7 +179,7 @@ public class RoleManager : IRoleManager
|
||||
{
|
||||
await _roleManagerRepository.TransactionAsync(async () =>
|
||||
{
|
||||
var existingRole = await _roleManagerRepository.GetRoleById(generalIdRef, cancellationToken);
|
||||
var existingRole = await _roleManagerRepository.GetRoleByIdAsync(generalIdRef, cancellationToken);
|
||||
if (existingRole == null || existingRole.Deleted)
|
||||
throw new NotFoundException("A role with this Id does not exist");
|
||||
|
||||
@ -191,7 +191,7 @@ public class RoleManager : IRoleManager
|
||||
|
||||
public async Task<IPaginatedData<RoleUser>> GetRoleUsers(Paging paging, GeneralIdRef roleId, CancellationToken cancellationToken)
|
||||
{
|
||||
var role = await _roleManagerRepository.GetRoleById(roleId, cancellationToken);
|
||||
var role = await _roleManagerRepository.GetRoleByIdAsync(roleId, cancellationToken);
|
||||
|
||||
var roleUsers = _roleManagerRepository.GetUserRoles();
|
||||
|
||||
@ -240,12 +240,12 @@ public class RoleManager : IRoleManager
|
||||
{
|
||||
await _roleManagerRepository.TransactionAsync(async () =>
|
||||
{
|
||||
var existingRole = await _roleManagerRepository.GetRoleById(userRoleIds.RoleId, cancellationToken);
|
||||
var existingRole = await _roleManagerRepository.GetRoleByIdAsync(userRoleIds.RoleId, cancellationToken);
|
||||
|
||||
if (existingRole == null || existingRole.Deleted)
|
||||
throw new NotFoundException("Role Not Found");
|
||||
|
||||
var existingUser = await _userManagerRepository.GetUserById(userRoleIds.UserId, cancellationToken);
|
||||
var existingUser = await _userManagerRepository.GetUserByIdAsync(userRoleIds.UserId, cancellationToken);
|
||||
|
||||
if (existingUser == null || !existingUser.Active)
|
||||
throw new NotFoundException("User not Found");
|
||||
@ -259,12 +259,12 @@ public class RoleManager : IRoleManager
|
||||
{
|
||||
await _roleManagerRepository.TransactionAsync(async () =>
|
||||
{
|
||||
var existingRole = await _roleManagerRepository.GetRoleById(userRoleIds.RoleId, cancellationToken);
|
||||
var existingRole = await _roleManagerRepository.GetRoleByIdAsync(userRoleIds.RoleId, cancellationToken);
|
||||
|
||||
if (existingRole == null || existingRole.Deleted)
|
||||
throw new NotFoundException("Role Not Found");
|
||||
|
||||
var existingUser = await _userManagerRepository.GetUserById(userRoleIds.UserId, cancellationToken);
|
||||
var existingUser = await _userManagerRepository.GetUserByIdAsync(userRoleIds.UserId, cancellationToken);
|
||||
|
||||
if (existingUser == null || !existingUser.Active)
|
||||
throw new NotFoundException("User not Found");
|
||||
@ -331,7 +331,7 @@ public class RoleManager : IRoleManager
|
||||
|
||||
public async Task AddRoleSecurityAccess(AuditUserDetails auditUserDetails, AddRoleSecurityAccess accessToAdd, CancellationToken cancellationToken)
|
||||
{
|
||||
var role = await _roleManagerRepository.GetRoleById(accessToAdd.RoleId, cancellationToken) ??
|
||||
var role = await _roleManagerRepository.GetRoleByIdAsync(accessToAdd.RoleId, cancellationToken) ??
|
||||
throw new NotFoundException("Role Not Found");
|
||||
|
||||
var rollAccessToAdd = accessToAdd.SecurityAccess.Select(
|
||||
@ -351,7 +351,7 @@ public class RoleManager : IRoleManager
|
||||
CancellationToken cancellationToken
|
||||
)
|
||||
{
|
||||
var role = await _roleManagerRepository.GetRoleById(accessToRemove.RoleId, cancellationToken) ??
|
||||
var role = await _roleManagerRepository.GetRoleByIdAsync(accessToRemove.RoleId, cancellationToken) ??
|
||||
throw new NotFoundException("Role Not Found");
|
||||
|
||||
var rollAccessToDelete = _roleManagerRepository.GetAccessForRole()
|
||||
@ -400,7 +400,7 @@ public class RoleManager : IRoleManager
|
||||
Id = userId
|
||||
};
|
||||
|
||||
var user = await _userManagerRepository.GetUserById(generalIdRef, CancellationToken.None) ??
|
||||
var user = await _userManagerRepository.GetUserByIdAsync(generalIdRef, CancellationToken.None) ??
|
||||
throw new NotFoundException("User Not Found");
|
||||
|
||||
if (!user.Active)
|
||||
@ -441,7 +441,7 @@ public class RoleManager : IRoleManager
|
||||
domainToCheck = await _domainRepository.GetDomainById(specificDomain, cancellationToken);
|
||||
else
|
||||
{
|
||||
var user = await _userManagerRepository.GetUserById(new GeneralIdRef
|
||||
var user = await _userManagerRepository.GetUserByIdAsync(new GeneralIdRef
|
||||
{
|
||||
Id = userId
|
||||
}, cancellationToken);
|
||||
|
||||
@ -145,7 +145,12 @@ public class FakeUserManagerRepository : FakeRepository, IUserManagerRepository
|
||||
return Users.BuildMock();
|
||||
}
|
||||
|
||||
public Task<User?> GetUserById(IGeneralIdRef generalIdRef, CancellationToken cancellationToken)
|
||||
public User? GetUserById(IGeneralIdRef generalIdRef)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Task<User?> GetUserByIdAsync(IGeneralIdRef generalIdRef, CancellationToken cancellationToken)
|
||||
{
|
||||
return Task.FromResult(Users.SingleOrDefault(x => x.Id == generalIdRef.Id || x.Guid == generalIdRef.Guid ));
|
||||
}
|
||||
|
||||
@ -47,7 +47,19 @@ public class UserManagerRepository : RepositoryBase, IUserManagerRepository
|
||||
return users.FirstOrDefault();
|
||||
}
|
||||
|
||||
public async Task<User?> GetUserById(IGeneralIdRef generalIdRef, CancellationToken cancellationToken)
|
||||
|
||||
public User? GetUserById(IGeneralIdRef generalIdRef)
|
||||
{
|
||||
var user = GetUsers().AsEnumerable().FindByGeneralIdRef(generalIdRef);
|
||||
if (user != null)
|
||||
{
|
||||
DatabaseDbContext.Entry(user).Reload(); // re-fetch from DB
|
||||
}
|
||||
|
||||
return user;
|
||||
}
|
||||
|
||||
public async Task<User?> GetUserByIdAsync(IGeneralIdRef generalIdRef, CancellationToken cancellationToken)
|
||||
{
|
||||
var user = await GetUsers().FindByGeneralIdRefAsync(generalIdRef, cancellationToken);
|
||||
if (user != null)
|
||||
|
||||
@ -261,7 +261,7 @@ public class UserManager : IUserManager
|
||||
ValidateEmail(userRegistration.Email);
|
||||
await CheckForExistingUserByEmail(userRegistration.Email, cancellationToken);
|
||||
|
||||
var currentUser = await _userManagerRepository.GetUserById(new GeneralIdRef
|
||||
var currentUser = await _userManagerRepository.GetUserByIdAsync(new GeneralIdRef
|
||||
{
|
||||
Id = auditUserDetails.UserId
|
||||
}, cancellationToken);
|
||||
@ -328,7 +328,7 @@ public class UserManager : IUserManager
|
||||
|
||||
public async Task<LoginResponse> RefreshToken(IGeneralIdRef id, CancellationToken cancellationToken)
|
||||
{
|
||||
var user = await _userManagerRepository.GetUserById(id, cancellationToken);
|
||||
var user = await _userManagerRepository.GetUserByIdAsync(id, cancellationToken);
|
||||
return RefreshToken(user);
|
||||
}
|
||||
|
||||
@ -418,7 +418,7 @@ public class UserManager : IUserManager
|
||||
{
|
||||
await _userManagerRepository.TransactionAsync(async () =>
|
||||
{
|
||||
var user = await _userManagerRepository.GetUserById(generalIdRef, cancellationToken)
|
||||
var user = await _userManagerRepository.GetUserByIdAsync(generalIdRef, cancellationToken)
|
||||
?? throw new NotFoundException("Unable to find user");
|
||||
|
||||
await DeactivateUser(auditUserDetails, user, cancellationToken);
|
||||
@ -627,7 +627,7 @@ public class UserManager : IUserManager
|
||||
{
|
||||
await _userManagerRepository.TransactionAsync(async () =>
|
||||
{
|
||||
var user = await _userManagerRepository.GetUserById(userId, cancellationToken)
|
||||
var user = await _userManagerRepository.GetUserByIdAsync(userId, cancellationToken)
|
||||
?? throw new NotFoundException("unable to find user");
|
||||
|
||||
if (!user.Active)
|
||||
@ -674,7 +674,7 @@ public class UserManager : IUserManager
|
||||
|
||||
public async Task<GetUser?> GetUserAsync(GeneralIdRef generalIdRef, CancellationToken cancellationToken)
|
||||
{
|
||||
var user = await _userManagerRepository.GetUserById(generalIdRef, cancellationToken)
|
||||
var user = await _userManagerRepository.GetUserByIdAsync(generalIdRef, cancellationToken)
|
||||
?? throw new NotFoundException("User not found");
|
||||
|
||||
return MapUser(user);
|
||||
@ -747,7 +747,7 @@ public class UserManager : IUserManager
|
||||
CancellationToken cancellationToken
|
||||
)
|
||||
{
|
||||
var user = await _userManagerRepository.GetUserById(generalIdRef, cancellationToken)
|
||||
var user = await _userManagerRepository.GetUserByIdAsync(generalIdRef, cancellationToken)
|
||||
?? throw new NotFoundException("User not found");
|
||||
|
||||
await SendEmailUserAction(auditUserDetails, user, EmailUserActionType.ConfirmEmailAddress, cancellationToken);
|
||||
@ -807,7 +807,7 @@ public class UserManager : IUserManager
|
||||
|
||||
public async Task TurnOfSsoForUser(AuditUserDetails auditUserDetails, GeneralIdRef generalIdRef, CancellationToken cancellationToken)
|
||||
{
|
||||
var user = await _userManagerRepository.GetUserById(generalIdRef, cancellationToken) ?? throw new NotFoundException("User not found");
|
||||
var user = await _userManagerRepository.GetUserByIdAsync(generalIdRef, cancellationToken) ?? throw new NotFoundException("User not found");
|
||||
|
||||
user.SsoProviderId = null;
|
||||
user.SsoSubject = string.Empty;
|
||||
@ -822,7 +822,7 @@ public class UserManager : IUserManager
|
||||
CancellationToken cancellationToken
|
||||
)
|
||||
{
|
||||
var user = await _userManagerRepository.GetUserById(generalIdRef, cancellationToken) ?? throw new NotFoundException("User not found");
|
||||
var user = await _userManagerRepository.GetUserByIdAsync(generalIdRef, cancellationToken) ?? throw new NotFoundException("User not found");
|
||||
|
||||
var singleUseGuid = new SingleUseGuid
|
||||
{
|
||||
@ -854,7 +854,7 @@ public class UserManager : IUserManager
|
||||
{
|
||||
await _userManagerRepository.TransactionAsync(async () =>
|
||||
{
|
||||
var user = await _userManagerRepository.GetUserById(userAuthenticationDetails.Id, cancellationToken)
|
||||
var user = await _userManagerRepository.GetUserByIdAsync(userAuthenticationDetails.Id, cancellationToken)
|
||||
?? throw new NotFoundException("User not found");
|
||||
|
||||
var userProfile = new UpdatedUserProfile
|
||||
|
||||
@ -2,18 +2,63 @@
|
||||
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
|
||||
{
|
||||
WorkflowVersion DeserialiseFromDatabase(e_suite.Database.Core.Tables.Workflow.WorkflowVersion dbVersion);
|
||||
Workflow.Core.WorkflowVersion DeserialiseFromDatabase(e_suite.Database.Core.Tables.Workflow.WorkflowVersion dbVersion);
|
||||
|
||||
Task<e_suite.Database.Core.Tables.Workflow.WorkflowVersion> SerialiseToDatabase(
|
||||
WorkflowVersion runtime,
|
||||
Workflow.Core.WorkflowVersion runtime,
|
||||
e_suite.Database.Core.Tables.Workflow.WorkflowVersion? dbObject = null,
|
||||
CancellationToken cancellationToken = default
|
||||
);
|
||||
@ -21,15 +66,31 @@ public interface IWorkflowConverter
|
||||
public class WorkflowConverter : IWorkflowConverter
|
||||
{
|
||||
private readonly IDomainRepository _domainRepository;
|
||||
private readonly IRoleManagerRepository _roleManagerRepository;
|
||||
private readonly IUserManagerRepository _userManagerRepository;
|
||||
|
||||
public WorkflowConverter(IDomainRepository domainRepository)
|
||||
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 WorkflowVersion DeserialiseFromDatabase(e_suite.Database.Core.Tables.Workflow.WorkflowVersion dbVersion)
|
||||
public Workflow.Core.WorkflowVersion DeserialiseFromDatabase(e_suite.Database.Core.Tables.Workflow.WorkflowVersion dbVersion)
|
||||
{
|
||||
var runtime = new WorkflowVersion
|
||||
var runtime = new Workflow.Core.WorkflowVersion
|
||||
{
|
||||
Id = dbVersion.Id,
|
||||
Guid = dbVersion.Guid,
|
||||
@ -47,14 +108,14 @@ public class WorkflowConverter : IWorkflowConverter
|
||||
|
||||
foreach (var def in dbVersion.Tasks)
|
||||
{
|
||||
var task = def.ToTask();
|
||||
var task = def.ToTask(_jsonSerializerOptions);
|
||||
runtime.Tasks.Add(task);
|
||||
}
|
||||
|
||||
return runtime;
|
||||
}
|
||||
|
||||
public async Task<e_suite.Database.Core.Tables.Workflow.WorkflowVersion> SerialiseToDatabase(WorkflowVersion runtime, e_suite.Database.Core.Tables.Workflow.WorkflowVersion? dbObject = null, CancellationToken cancellationToken = default)
|
||||
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();
|
||||
@ -111,4 +172,20 @@ public class WorkflowTemplateRepository : RepositoryBase, IWorkflowTemplateRepos
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
@ -11,6 +11,8 @@ 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;
|
||||
|
||||
@ -23,11 +25,12 @@ public class WorkflowTemplateManager : IWorkflowTemplateManager
|
||||
private readonly IDomainRepository _domainRepository;
|
||||
private readonly IPatchFactory _patchFactory;
|
||||
|
||||
public WorkflowTemplateManager(IWorkflowTemplateRepository workflowTemplateRepository, IPatchFactory patchFactory, IDomainRepository domainRepository)
|
||||
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)
|
||||
@ -123,10 +126,45 @@ public class WorkflowTemplateManager : IWorkflowTemplateManager
|
||||
CancellationToken cancellationToken
|
||||
)
|
||||
{
|
||||
await _workflowTemplateRepository.TransactionAsync(async () =>
|
||||
{
|
||||
if (_workflowTemplateRepository.GetWorkflows().FirstOrDefault(x => x.Name == template.WorkflowName) !=
|
||||
null)
|
||||
{
|
||||
throw new ExistsException("Workflow already exists");
|
||||
}
|
||||
|
||||
//var workflowTemplate = _workflowConverter.DeserialiseFromDatabase(dbWorkflowTemplate);
|
||||
var workflow = new Database.Core.Tables.Workflow.Workflow
|
||||
{
|
||||
Name = template.WorkflowName,
|
||||
Guid = Guid.NewGuid()
|
||||
};
|
||||
|
||||
throw new NotImplementedException();
|
||||
await _workflowTemplateRepository.AddWorkflow(auditUserDetails, workflow, cancellationToken);
|
||||
|
||||
var workflowDomain = await _domainRepository.GetDomainById(template.DomainId, cancellationToken);
|
||||
|
||||
var dbWorkflowTemplate = new WorkflowVersion
|
||||
{
|
||||
Guid = Guid.NewGuid(),
|
||||
ActivityNameTemplate = template.ActivityNameTemplate,
|
||||
Description = template.Description,
|
||||
Domain = workflowDomain,
|
||||
Tasks = template.Tasks,
|
||||
Workflow = workflow,
|
||||
};
|
||||
|
||||
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)
|
||||
|
||||
@ -1,7 +1,12 @@
|
||||
using e_suite.Database.Core.Models;
|
||||
using e_suite.Database.Core.Tables.Contacts;
|
||||
using e_suite.Database.Core.Tables.Domain;
|
||||
using e_suite.Workflow.Core.Attributes;
|
||||
using e_suite.Workflow.Core.Interfaces;
|
||||
using eSuite.Core.Miscellaneous;
|
||||
using System.Reflection;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace e_suite.Workflow.Core.Extensions;
|
||||
|
||||
@ -30,7 +35,7 @@ public static class TaskExtensions
|
||||
return dictionary;
|
||||
}
|
||||
|
||||
public static ITask ToTask(this TaskDefinition definition)
|
||||
public static ITask ToTask(this TaskDefinition definition, JsonSerializerOptions jsonSerializerOptions)
|
||||
{
|
||||
var type = Type.GetType(definition.Type);
|
||||
|
||||
@ -42,28 +47,41 @@ public static class TaskExtensions
|
||||
if (instance == null)
|
||||
throw new InvalidOperationException($"Type '{definition.Type}' does not implement ITask.");
|
||||
|
||||
FromConfigDictionary(instance, definition.Config);
|
||||
FromConfigDictionary(instance, definition.Config, jsonSerializerOptions);
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
public static void FromConfigDictionary(this object obj, Dictionary<string, object?> dict)
|
||||
public static void FromConfigDictionary(this object obj, Dictionary<string, object?> dict, JsonSerializerOptions jsonSerializerOptions)
|
||||
{
|
||||
var type = obj.GetType();
|
||||
|
||||
foreach (var kvp in dict)
|
||||
{
|
||||
var prop = type.GetProperty(kvp.Key);
|
||||
var prop = type.GetProperty(
|
||||
kvp.Key,
|
||||
BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase
|
||||
);
|
||||
|
||||
if (prop == null || !prop.CanWrite)
|
||||
continue;
|
||||
|
||||
var targetType = prop.PropertyType;
|
||||
var value = kvp.Value;
|
||||
|
||||
// Handle enums (the only case where JSON gives you a string)
|
||||
if (value != null && targetType.IsEnum)
|
||||
// If the value is a JsonElement, convert it to the target type
|
||||
if (value is JsonElement je)
|
||||
{
|
||||
value = Enum.Parse(targetType, value.ToString()!, ignoreCase: true);
|
||||
if (targetType.IsEnum)
|
||||
{
|
||||
// Enums come through as strings
|
||||
value = Enum.Parse(targetType, je.GetString()!, ignoreCase: true);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Deserialize JSON into the target type (handles lists, objects, primitives)
|
||||
value = JsonSerializer.Deserialize(je.GetRawText(), targetType, jsonSerializerOptions);
|
||||
}
|
||||
}
|
||||
|
||||
prop.SetValue(obj, value);
|
||||
|
||||
@ -7,6 +7,6 @@ namespace e_suite.Workflow.Core.Interfaces;
|
||||
public interface IAssignees<T> where T : ITaskAssignee
|
||||
{
|
||||
[Required]
|
||||
IList<T> Assignees { get; }
|
||||
List<T> Assignees { get; set; }
|
||||
|
||||
}
|
||||
@ -1,5 +1,5 @@
|
||||
using e_suite.Database.Core.Tables.Contacts;
|
||||
using e_suite.Database.Core.Tables.Domain;
|
||||
using e_suite.Database.Core.Tables.Domain;
|
||||
using e_suite.Database.Core.Tables.UserManager;
|
||||
using e_suite.Workflow.Core.Attributes;
|
||||
using e_suite.Workflow.Core.Enums;
|
||||
|
||||
@ -9,7 +9,7 @@ namespace e_suite.Workflow.Core.Interfaces;
|
||||
public interface ITaskAssignee
|
||||
{
|
||||
public Role? Role { get; set; }
|
||||
public Contact? Contact { get; set; }
|
||||
public User? User { get; set; }
|
||||
|
||||
public Raci Raci { get; set; }
|
||||
}
|
||||
@ -1,6 +1,6 @@
|
||||
using e_suite.Database.Core.Tables.Contacts;
|
||||
using e_suite.Database.Core.Tables.Domain;
|
||||
using e_suite.Database.Core.Tables.Domain;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using e_suite.Database.Core.Tables.UserManager;
|
||||
using e_suite.Workflow.Core.Enums;
|
||||
using e_suite.Workflow.Core.Interfaces;
|
||||
|
||||
@ -9,16 +9,16 @@ namespace e_suite.Workflow.Core;
|
||||
public class TaskAssignee : ITaskAssignee, IValidatableObject
|
||||
{
|
||||
public Role? Role { get; set; }
|
||||
public Contact? Contact { get; set; }
|
||||
public User? User { get; set; }
|
||||
public Raci Raci { get; set; }
|
||||
|
||||
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
|
||||
{
|
||||
if (!((Role != null) ^ (Contact != null))) //Role Xor Contact means either must be set, but not both the same
|
||||
if (!((Role != null) ^ (User != null))) //Role Xor Contact means either must be set, but not both the same
|
||||
{
|
||||
yield return new ValidationResult(
|
||||
"Either Role or Contact must be set, but not both.",
|
||||
[nameof(Role), nameof(Contact)]
|
||||
[nameof(Role), nameof(User)]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,9 +5,9 @@ using e_suite.Workflow.Core.Interfaces;
|
||||
namespace e_suite.Workflow.Core.Tasks;
|
||||
|
||||
[GeneralTask]
|
||||
public class AdhocApprovalTask : TaskBase, IAssignees<IApprovalTaskAssignee>, IOutcome<ApprovalVerdict>
|
||||
public class AdhocApprovalTask : TaskBase, IAssignees<ApprovalTaskAssignee>, IOutcome<ApprovalVerdict>
|
||||
{
|
||||
public IList<IApprovalTaskAssignee> Assignees { get; } = new List<IApprovalTaskAssignee>();
|
||||
public List<ApprovalTaskAssignee> Assignees { get; set; } = [];
|
||||
public ApprovalVerdict TaskOutcome { get; set; }
|
||||
public Dictionary<ApprovalVerdict, Guid> OutcomeActions { get; set; }
|
||||
public bool OverrideDefaultTaskProgression { get; set; }
|
||||
|
||||
@ -4,8 +4,8 @@ using e_suite.Workflow.Core.Interfaces;
|
||||
namespace e_suite.Workflow.Core.Tasks;
|
||||
|
||||
[ApprovalTask]
|
||||
public class ApprovalStep : TaskBase, IAssignees<IApprovalTaskAssignee>
|
||||
public class ApprovalStep : TaskBase, IAssignees<ApprovalTaskAssignee>
|
||||
{
|
||||
public IList<IApprovalTaskAssignee> Assignees { get; } = [];
|
||||
public List<ApprovalTaskAssignee> Assignees { get; set; } = [];
|
||||
|
||||
}
|
||||
@ -8,7 +8,7 @@ namespace e_suite.Workflow.Core.Tasks;
|
||||
/// A user has to open this task, manually set it to ready to complete
|
||||
/// </summary>
|
||||
[GeneralTask]
|
||||
public class BasicTask : TaskBase, IAssignees<ITaskAssignee>
|
||||
public class BasicTask : TaskBase, IAssignees<TaskAssignee>
|
||||
{
|
||||
public IList<ITaskAssignee> Assignees { get; }
|
||||
public List<TaskAssignee> Assignees { get; set; } = [];
|
||||
}
|
||||
@ -7,7 +7,7 @@ namespace e_suite.Workflow.Core.Tasks;
|
||||
/// Create a table of field data for output to PDF or AdobeIllustrator
|
||||
/// </summary>
|
||||
[GeneralTask]
|
||||
public class ContentCollationTask : TaskBase, IAssignees<ITaskAssignee>
|
||||
public class ContentCollationTask : TaskBase, IAssignees<TaskAssignee>
|
||||
{
|
||||
public IList<ITaskAssignee> Assignees { get; } = [];
|
||||
public List<TaskAssignee> Assignees { get; set; } = [];
|
||||
}
|
||||
@ -5,9 +5,9 @@ using eSuite.Core.Miscellaneous;
|
||||
namespace e_suite.Workflow.Core.Tasks;
|
||||
|
||||
[GeneralTask]
|
||||
public class FormDataInputTask : TaskBase, IAssignees<ITaskAssignee>, IFormTemplate
|
||||
public class FormDataInputTask : TaskBase, IAssignees<TaskAssignee>, IFormTemplate
|
||||
{
|
||||
public IList<ITaskAssignee> Assignees { get; } = new List<ITaskAssignee>();
|
||||
public List<TaskAssignee> Assignees { get; set; } = [];
|
||||
public bool IsMultiple { get; set; }
|
||||
public required IGeneralIdRef FormIdRef { get; set; }
|
||||
|
||||
|
||||
@ -9,10 +9,10 @@
|
||||
</TestAncestor>
|
||||
</SessionState></s:String>
|
||||
<s:Boolean x:Key="/Default/Housekeeping/Bookmarks/NumberedBookmarks/=Bookmark1/@KeyIndexDefined">True</s:Boolean>
|
||||
<s:String x:Key="/Default/Housekeeping/Bookmarks/NumberedBookmarks/=Bookmark1/Coords/@EntryValue">(Doc Ln 140 Col 8)</s:String>
|
||||
<s:String x:Key="/Default/Housekeeping/Bookmarks/NumberedBookmarks/=Bookmark1/FileId/@EntryValue">4A704FA7-4E3A-4CFA-B043-434A0C49AF89/d:Translation/f:TranslatorFactory.cs</s:String>
|
||||
<s:String x:Key="/Default/Housekeeping/Bookmarks/NumberedBookmarks/=Bookmark1/Coords/@EntryValue">(Doc Ln 85 Col 88)</s:String>
|
||||
<s:String x:Key="/Default/Housekeeping/Bookmarks/NumberedBookmarks/=Bookmark1/FileId/@EntryValue">92811343-6BCB-D7E5-63D9-2F6A56AE182C/d:Extensions/f:TaskExtensions.cs</s:String>
|
||||
<s:String x:Key="/Default/Housekeeping/Bookmarks/NumberedBookmarks/=Bookmark1/Owner/@EntryValue">NumberedBookmarkManager</s:String>
|
||||
<s:Boolean x:Key="/Default/Housekeeping/Bookmarks/NumberedBookmarks/=Bookmark2/@KeyIndexDefined">True</s:Boolean>
|
||||
<s:String x:Key="/Default/Housekeeping/Bookmarks/NumberedBookmarks/=Bookmark2/Coords/@EntryValue">(Doc Ln 606 Col 8)</s:String>
|
||||
<s:String x:Key="/Default/Housekeeping/Bookmarks/NumberedBookmarks/=Bookmark2/FileId/@EntryValue">A00B7AED-96DF-49A5-BA8F-9BE74021F3CF/f:UserManager.cs</s:String>
|
||||
<s:String x:Key="/Default/Housekeeping/Bookmarks/NumberedBookmarks/=Bookmark2/Coords/@EntryValue">(Doc Ln 81 Col 0)</s:String>
|
||||
<s:String x:Key="/Default/Housekeeping/Bookmarks/NumberedBookmarks/=Bookmark2/FileId/@EntryValue">92811343-6BCB-D7E5-63D9-2F6A56AE182C/d:Extensions/f:TaskExtensions.cs</s:String>
|
||||
<s:String x:Key="/Default/Housekeeping/Bookmarks/NumberedBookmarks/=Bookmark2/Owner/@EntryValue">NumberedBookmarkManager</s:String></wpf:ResourceDictionary>
|
||||
Loading…
Reference in New Issue
Block a user