Improved compliance monitoring

This commit is contained in:
2026-10-22 15:42:36 +02:00
parent 9835121fd9
commit 299d6ff4dc
27 changed files with 4245 additions and 149 deletions
@@ -20,6 +20,27 @@ public sealed class ProjectService(IDbContextFactory<ApplicationDbContext> conte
if (!await context.Users.AnyAsync(u => u.Id == userId, cancellationToken))
return Result.Fail(NotFoundError.New);
if (request.Status == ApprovalStatus.Approved)
{
var hasUnmetCompliance = await context.ComplianceItems
.AnyAsync(c => c.ProjectId == request.ProjectId && c.Status == ComplianceStatus.NotMet, cancellationToken);
if (hasUnmetCompliance)
return Result.Fail(ValidationError.Create("Project cannot be approved because some compliance items are not met."));
var projectBeneficiaryIds = await context.Beneficiaries
.Where(b => b.ProjectId == request.ProjectId)
.Select(b => b.Id)
.ToListAsync(cancellationToken);
if (projectBeneficiaryIds.Count > 0)
{
var hasUnmetOutcomes = await context.Outcomes
.AnyAsync(o => projectBeneficiaryIds.Contains(o.BeneficiaryId) && o.Status == ComplianceStatus.NotMet, cancellationToken);
if (hasUnmetOutcomes)
return Result.Fail(ValidationError.Create("Project cannot be approved because some beneficiary outcomes are not met."));
}
}
var changedTotal = await context.Projects
.Where(f => f.Id == request.ProjectId)
.ExecuteUpdateAsync(f => f
@@ -544,8 +565,9 @@ public sealed class ProjectService(IDbContextFactory<ApplicationDbContext> conte
CreatedAt = DateTime.UtcNow,
CreatedBy = userId,
ProjectId = request.ProjectId,
BeneficiaryId = request.BeneficiaryId,
Requirements = request.Requirements,
Status = ApprovalStatus.Pending,
Status = request.Status,
TenantId = tenantContext.TenantId,
Title = request.Title.Humanize(LetterCasing.Title).Trim()
});
@@ -563,7 +585,10 @@ public sealed class ProjectService(IDbContextFactory<ApplicationDbContext> conte
.ExecuteUpdateAsync(f => f
.SetProperty(u => u.Title, request.Title.Humanize(LetterCasing.Title).Trim())
.SetProperty(u => u.Requirements, request.Requirements)
.SetProperty(u => u.Status, request.Status), cancellationToken);
.SetProperty(u => u.BeneficiaryId, request.BeneficiaryId)
.SetProperty(u => u.Status, request.Status)
.SetProperty(u => u.UpdatedAt, DateTime.UtcNow)
.SetProperty(u => u.VerifiedBy, userId), cancellationToken);
return Result.OkIf(changedTotal > 0, UpdateError.Create("No records changed"));
}));
@@ -768,6 +793,7 @@ public sealed class ProjectService(IDbContextFactory<ApplicationDbContext> conte
CreatedBy = userId,
Description = request.Description,
Name = request.Name.Humanize(LetterCasing.Title).Trim(),
Status = request.Status,
TenantId = tenantContext.TenantId
});
@@ -783,7 +809,8 @@ public sealed class ProjectService(IDbContextFactory<ApplicationDbContext> conte
.Where(o => o.Id == request.OutcomeId)
.ExecuteUpdateAsync(f => f
.SetProperty(u => u.Description, request.Description)
.SetProperty(u => u.Name, request.Name.Humanize(LetterCasing.Title).Trim()), cancellationToken);
.SetProperty(u => u.Name, request.Name.Humanize(LetterCasing.Title).Trim())
.SetProperty(u => u.Status, request.Status), cancellationToken);
return Result.OkIf(changedTotal > 0, UpdateError.Create("No records changed"));
}));