feat(infrastructure): add DB options and workflow close outcome evaluation
This commit is contained in:
@@ -1,15 +1,18 @@
|
||||
using DigitalData.TaskFlow.Application.Common.Interfaces;
|
||||
using DigitalData.TaskFlow.Domain.Closing;
|
||||
using DigitalData.TaskFlow.Domain.Workflows;
|
||||
using DigitalData.TaskFlow.Infrastructure.Options;
|
||||
using DigitalData.TaskFlow.Infrastructure.Persistence;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Options;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace DigitalData.TaskFlow.Infrastructure.Repositories;
|
||||
|
||||
/// <summary>
|
||||
/// Workflow repository implementation for reading workflow listing data and applying close operations.
|
||||
/// </summary>
|
||||
public sealed class WorkflowRepository(TaskFlowDbContext dbContext) : IWorkflowRepository
|
||||
public sealed class WorkflowRepository(TaskFlowDbContext dbContext, IOptions<DatabaseOptions> databaseOptions) : IWorkflowRepository
|
||||
{
|
||||
/// <summary>
|
||||
/// Retrieves grouped workflow data for a user.
|
||||
@@ -20,7 +23,9 @@ public sealed class WorkflowRepository(TaskFlowDbContext dbContext) : IWorkflowR
|
||||
public async Task<WorkflowSourcesResponse> GetAsync(int wisagId, CancellationToken cancellationToken)
|
||||
{
|
||||
const string resultType = "table";
|
||||
const string objectType = "Ferdinand";
|
||||
var objectType = string.IsNullOrWhiteSpace(databaseOptions.Value.WorkflowListingObjectType)
|
||||
? "Ferdinand"
|
||||
: databaseOptions.Value.WorkflowListingObjectType;
|
||||
|
||||
var rows = await dbContext
|
||||
.WorkflowListingReadModels
|
||||
@@ -28,6 +33,19 @@ public sealed class WorkflowRepository(TaskFlowDbContext dbContext) : IWorkflowR
|
||||
.AsNoTracking()
|
||||
.ToListAsync(cancellationToken);
|
||||
|
||||
if (rows.Count == 0)
|
||||
{
|
||||
var metaCode = await TryGetWorkflowMetaCodeAsync(wisagId, objectType, cancellationToken);
|
||||
|
||||
if (metaCode == 2)
|
||||
{
|
||||
return new WorkflowSourcesResponse
|
||||
{
|
||||
Sources = []
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
var listing = rows
|
||||
.Select(row => new WorkflowListingItem
|
||||
{
|
||||
@@ -94,7 +112,119 @@ public sealed class WorkflowRepository(TaskFlowDbContext dbContext) : IWorkflowR
|
||||
CloseWorkflowDecision decision,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
throw new NotSupportedException(
|
||||
"Closing write procedure is not finalized yet. Configure final DB procedure mapping before enabling CloseAsync.");
|
||||
_ = decision;
|
||||
|
||||
if (!string.Equals(source, "Ferdinand", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return Task.FromResult(new CloseWorkflowResult
|
||||
{
|
||||
ProcessId = processId,
|
||||
IsClosed = false,
|
||||
Outcome = CloseWorkflowOutcome.NotFound
|
||||
});
|
||||
}
|
||||
|
||||
return EvaluateCloseOutcomeAsync(wisagId, processId, cancellationToken);
|
||||
}
|
||||
|
||||
private async Task<CloseWorkflowResult> EvaluateCloseOutcomeAsync(
|
||||
int wisagId,
|
||||
int processId,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var activeForUser = await dbContext.Database
|
||||
.SqlQuery<int>($"SELECT COUNT(1) FROM dbo.TBCUST_F19_LISTING_RESULT WHERE userid = {wisagId} AND processid = {processId}")
|
||||
.SingleAsync(cancellationToken);
|
||||
|
||||
if (activeForUser > 0)
|
||||
{
|
||||
return new CloseWorkflowResult
|
||||
{
|
||||
ProcessId = processId,
|
||||
IsClosed = true,
|
||||
Outcome = CloseWorkflowOutcome.Closed
|
||||
};
|
||||
}
|
||||
|
||||
var activeAnyUser = await dbContext.Database
|
||||
.SqlQuery<int>($"SELECT COUNT(1) FROM dbo.TBCUST_F19_LISTING_RESULT WHERE processid = {processId}")
|
||||
.SingleAsync(cancellationToken);
|
||||
|
||||
if (activeAnyUser > 0)
|
||||
{
|
||||
return new CloseWorkflowResult
|
||||
{
|
||||
ProcessId = processId,
|
||||
IsClosed = false,
|
||||
Outcome = CloseWorkflowOutcome.NoAccess
|
||||
};
|
||||
}
|
||||
|
||||
var inHistory = await dbContext.Database
|
||||
.SqlQuery<int>($"SELECT COUNT(1) FROM dbo.TBMWF_PROFILE_OBJ_STATE_HISTORY WHERE OBJ_ID = {processId}")
|
||||
.SingleAsync(cancellationToken);
|
||||
|
||||
if (inHistory > 0)
|
||||
{
|
||||
return new CloseWorkflowResult
|
||||
{
|
||||
ProcessId = processId,
|
||||
IsClosed = false,
|
||||
Outcome = CloseWorkflowOutcome.AlreadyClosed
|
||||
};
|
||||
}
|
||||
|
||||
return new CloseWorkflowResult
|
||||
{
|
||||
ProcessId = 0,
|
||||
IsClosed = false,
|
||||
Outcome = CloseWorkflowOutcome.NotFound
|
||||
};
|
||||
}
|
||||
|
||||
private async Task<int?> TryGetWorkflowMetaCodeAsync(int wisagId, string objectType, CancellationToken cancellationToken)
|
||||
{
|
||||
const string resultType = "json";
|
||||
|
||||
var jsonPayload = await dbContext.Database
|
||||
.SqlQuery<string>($"EXEC dbo.PRCUST_F19_GET_LISTING_DATA @pUSER_ID={wisagId}, @pRESULT_TYPE={resultType}, @pOBJECT_TYPE={objectType}")
|
||||
.AsNoTracking()
|
||||
.FirstOrDefaultAsync(cancellationToken);
|
||||
|
||||
if (string.IsNullOrWhiteSpace(jsonPayload))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
using var document = JsonDocument.Parse(jsonPayload);
|
||||
|
||||
if (!document.RootElement.TryGetProperty("response", out var responseElement))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!responseElement.TryGetProperty("meta", out var metaElement) || metaElement.ValueKind != JsonValueKind.Array)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (metaElement.GetArrayLength() == 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!metaElement[0].TryGetProperty("code", out var codeElement))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return codeElement.GetInt32();
|
||||
}
|
||||
catch (JsonException)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user