107 lines
4.1 KiB
C#
107 lines
4.1 KiB
C#
using e_suite.API.Common.repository;
|
|
using e_suite.Database.Audit;
|
|
using e_suite.Database.Core.Tables.Activity;
|
|
using e_suite.Workflow.Core;
|
|
using e_suite.Workflow.Core.Interfaces;
|
|
using eSuite.Core.Clock;
|
|
using eSuite.Core.Enums;
|
|
using eSuite.Core.Miscellaneous;
|
|
using Microsoft.Extensions.Logging;
|
|
|
|
namespace e_suite.Service.WorkflowProcessor;
|
|
|
|
public class WorkflowProcessor : IWorkflowProcessor
|
|
{
|
|
private readonly ILogger _logger;
|
|
private readonly IClock _clock;
|
|
private readonly IWorkflowTemplateRepository _workflowTemplateRepository;
|
|
private readonly IWorkflowConverter _workflowConverter;
|
|
private readonly IActivityRepository _activityRepository;
|
|
|
|
public WorkflowProcessor(ILogger logger, IClock clock, IWorkflowTemplateRepository workflowTemplateRepository, IActivityRepository activityRepository, IWorkflowConverter workflowConverter)
|
|
{
|
|
_logger = logger;
|
|
_clock = clock;
|
|
_workflowTemplateRepository = workflowTemplateRepository;
|
|
_activityRepository = activityRepository;
|
|
_workflowConverter = workflowConverter;
|
|
}
|
|
|
|
public async Task ProgressActivity(
|
|
AuditUserDetails auditUserDetails,
|
|
GeneralIdRef activityId,
|
|
CancellationToken cancellationToken
|
|
)
|
|
{
|
|
_logger.LogInformation("{DateTime}: Progressing Activity {messageId}", _clock.GetNow, activityId);
|
|
|
|
var activityInstance = await _activityRepository.GetActivityInstanceAsync(activityId, cancellationToken);
|
|
if (activityInstance == null)
|
|
{
|
|
_logger.LogInformation("{DateTime}: Unable to find activity {messageId}", _clock.GetNow, activityId);
|
|
throw new InvalidDataException("activityInstance not found");
|
|
}
|
|
|
|
if (activityInstance.ActivityState == ActivityState.Cancelled)
|
|
{
|
|
_logger.LogInformation("{DateTime}: Activity {messageId} is cancelled, skipping", _clock.GetNow,
|
|
activityId);
|
|
return;
|
|
}
|
|
|
|
if (activityInstance.ActivityState == ActivityState.Completed)
|
|
{
|
|
_logger.LogInformation("{DateTime}: Activity {messageId} is already completed, skipping", _clock.GetNow,
|
|
activityId);
|
|
return;
|
|
}
|
|
|
|
var workflowVersion = _workflowConverter.DeserialiseFromDatabase(activityInstance.WorkflowVersion);
|
|
|
|
await _activityRepository.TransactionAsync(async () =>
|
|
{
|
|
|
|
ICollection<ActivityTask> tasks;
|
|
if (activityInstance.ActivityState == ActivityState.Pending)
|
|
{
|
|
activityInstance.ActivityState = ActivityState.Active;
|
|
await _activityRepository.UpdateActivityInstanceAsync(auditUserDetails, activityInstance,
|
|
cancellationToken);
|
|
|
|
tasks = await PlanTaskExecution(auditUserDetails, activityInstance, workflowVersion, cancellationToken);
|
|
}
|
|
else
|
|
{
|
|
tasks = activityInstance.Tasks;
|
|
}
|
|
|
|
//Invoke startable tasks.
|
|
});
|
|
}
|
|
|
|
private async Task<ICollection<ActivityTask>> PlanTaskExecution(AuditUserDetails auditUserDetails, Activity activityInstance, WorkflowVersion workflowVersion, CancellationToken cancellationToken)
|
|
{
|
|
var activityOrdinalCounter = 1;
|
|
|
|
//Create task instances for the activity
|
|
var activityTasks = new List<ActivityTask>();
|
|
|
|
foreach (var task in workflowVersion.Tasks)
|
|
{
|
|
var activityTask = new ActivityTask
|
|
{
|
|
Guid = Guid.NewGuid(),
|
|
Activity = activityInstance,
|
|
ActivityState = ActivityState.Pending,
|
|
TaskGuid = task.Guid,
|
|
ActivityOrdinal = activityOrdinalCounter++,
|
|
TaskName = task.Name,
|
|
};
|
|
activityTasks.Add(activityTask);
|
|
|
|
}
|
|
await _activityRepository.AddActivityTasksAsync(auditUserDetails, activityTasks, cancellationToken);
|
|
|
|
return activityTasks;
|
|
}
|
|
} |