using Jiaowu.Api.Domain.Academic; namespace Jiaowu.Api.Infrastructure.Graduation; public enum StudentCourseProgressStatus { NotStarted = 1, InProgress = 2, Retaking = 3, Completed = 4, Failed = 5, Pending = 6 } public sealed record StudentCourseAttemptSnapshot( decimal? TotalScore, GradeExamStatus ExamStatus); public sealed record StudentCourseProgressEvaluation( StudentCourseProgressStatus Status, bool HasPassedAttempt, bool HasFailedAttempt); public static class StudentCourseProgressRules { public static StudentCourseProgressEvaluation Evaluate( IEnumerable attempts, bool isInProgress) { var attemptList = attempts.ToList(); var hasPassedAttempt = attemptList.Any(IsPassed); var hasFailedAttempt = attemptList.Any(IsFailed); var hasPendingAttempt = attemptList.Any(x => !IsPassed(x) && !IsFailed(x)); var status = hasPassedAttempt ? StudentCourseProgressStatus.Completed : isInProgress && hasFailedAttempt ? StudentCourseProgressStatus.Retaking : isInProgress ? StudentCourseProgressStatus.InProgress : hasFailedAttempt ? StudentCourseProgressStatus.Failed : hasPendingAttempt ? StudentCourseProgressStatus.Pending : StudentCourseProgressStatus.NotStarted; return new StudentCourseProgressEvaluation( status, hasPassedAttempt, hasFailedAttempt); } public static bool IsPassed(StudentCourseAttemptSnapshot attempt) => attempt.ExamStatus == GradeExamStatus.Exempt || attempt.TotalScore is decimal score && score >= 60; public static bool IsFailed(StudentCourseAttemptSnapshot attempt) => attempt.ExamStatus == GradeExamStatus.Absent || attempt.TotalScore is decimal score && score < 60; }