Improved compliance monitoring
This commit is contained in:
@@ -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"));
|
||||
}));
|
||||
|
||||
@@ -15,11 +15,13 @@ public sealed record CreateSiteVisitRequest([Required] long ProjectId,
|
||||
|
||||
public sealed record UpdateOutcomeRequest([Required] long OutcomeId,
|
||||
[Required][MaxLength(LabelLength)] string Name,
|
||||
[Required][MaxLength(TextLength)] string Description);
|
||||
[Required][MaxLength(TextLength)] string Description,
|
||||
[Required] ComplianceStatus Status = ComplianceStatus.NotMet);
|
||||
|
||||
public sealed record CreateOutcomeRequest([Required] long BeneficiaryId,
|
||||
[Required][MaxLength(LabelLength)] string Name,
|
||||
[Required][MaxLength(TextLength)] string Description);
|
||||
[Required][MaxLength(TextLength)] string Description,
|
||||
ComplianceStatus Status = ComplianceStatus.NotMet);
|
||||
|
||||
public sealed record UpdateIssueRequest([Required] long IssueId,
|
||||
[Required][MaxLength(LabelLength)] string Title,
|
||||
@@ -53,11 +55,14 @@ public sealed record CreateBeneficiaryRequest([Required] long ProjectId,
|
||||
public sealed record UpdateComplianceItemRequest([Required] long ComplianceItemId,
|
||||
[Required][MaxLength(LabelLength)] string Title,
|
||||
[Required][MaxLength(TextLength)] string Requirements,
|
||||
[Required] ApprovalStatus Status);
|
||||
[Required] ComplianceStatus Status,
|
||||
long? BeneficiaryId = null);
|
||||
|
||||
public sealed record CreateComplianceItemRequest([Required] long ProjectId,
|
||||
[Required][MaxLength(LabelLength)] string Title,
|
||||
[Required][MaxLength(TextLength)] string Requirements);
|
||||
[Required][MaxLength(TextLength)] string Requirements,
|
||||
ComplianceStatus Status = ComplianceStatus.NotMet,
|
||||
long? BeneficiaryId = null);
|
||||
|
||||
public sealed record UpdateChangeRequest([Required] long ChangeRequestId,
|
||||
[Required][MaxLength(LabelLength)] string Title,
|
||||
|
||||
Reference in New Issue
Block a user