using System; using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; using GB5Shared.DTO.Framework.Login; using GB5Shared.DTO.Framework.Validation; namespace GB5Shared.ValidationCriteria { public class ValidationCriteriaEvaluator : IValidationCriteriaEvaluator { private const byte VALIDATIONTYPE_SKILL = 1; private const byte VALIDATIONTYPE_QUIZ = 2; private const byte VALIDATIONTYPE_PROGRAMME_ASSESSMENT = 3; private const byte VALIDATIONTYPE_CERTIFICATION = 4; private readonly IValidationAssignmentDAL _ValidationAssignmentDAL; public ValidationCriteriaEvaluator(IValidationAssignmentDAL validationAssignmentDAL) { _ValidationAssignmentDAL = validationAssignmentDAL; } public async Task> GetUnmetValidationCriteriaAsync( short entityType, int entityId, int entityStepId, int employeeId, LoginDTO login, CancellationToken ct) { var assignments = await _ValidationAssignmentDAL.GetAssignmentsWithCriteriaForEntity(entityType, entityId, entityStepId, login) .ConfigureAwait(false); var unmet = new List(); foreach (var a in assignments) { var status = await EvaluateOneAsync(a, employeeId, login).ConfigureAwait(false); if (status == ValidationCriteriaStatus.Met) continue; unmet.Add(new ValidationCriteriaResultDTO { ValidationAssignmentId = a.ValidationAssignmentId, ValidationCriteriaId = a.ValidationCriteriaId, ValidationType = a.ValidationType, Description = a.Description, Enforcement = a.Enforcement, IsMandatory = a.IsMandatory, Status = status }); } return unmet; } private async Task EvaluateOneAsync( ValidationAssignmentWithCriteriaDTO a, int employeeId, LoginDTO login) { switch (a.ValidationType) { case VALIDATIONTYPE_SKILL: { var level = await _ValidationAssignmentDAL.GetEmployeeSkillLevel(employeeId, a.TargetId, login).ConfigureAwait(false); return (level.HasValue && level.Value >= a.MinLevel) ? ValidationCriteriaStatus.Met : ValidationCriteriaStatus.NotMet; } case VALIDATIONTYPE_QUIZ: { var completedOn = await _ValidationAssignmentDAL.GetLatestPassingQuizAttemptCompletedOn(a.TargetId, employeeId, login).ConfigureAwait(false); return IsWithinValidity(completedOn, a.ValidityDays) ? ValidationCriteriaStatus.Met : ValidationCriteriaStatus.NotMet; } case VALIDATIONTYPE_PROGRAMME_ASSESSMENT: { var completedOn = await _ValidationAssignmentDAL.GetLatestPassingAssessmentAttemptCompletedOn(a.TargetId, employeeId, login).ConfigureAwait(false); return IsWithinValidity(completedOn, a.ValidityDays) ? ValidationCriteriaStatus.Met : ValidationCriteriaStatus.NotMet; } case VALIDATIONTYPE_CERTIFICATION: default: // No universal certification/data-record table exists in this repo today — not // implemented generically. Report Unverifiable rather than silently claiming Met. return ValidationCriteriaStatus.Unverifiable; } } private static bool IsWithinValidity(DateTime? completedOn, int validityDays) { if (!completedOn.HasValue) return false; if (validityDays < 0) return true; // -1 = never expires return completedOn.Value >= DateTime.UtcNow.AddDays(-validityDays); } } }