using Jiaowu.Api.Domain.Academic; namespace Jiaowu.Api.Infrastructure.Grades; public static class ExperimentGradeCalculator { public static bool AreWeightsValid( decimal contributionWeight, decimal passScore, IEnumerable items) { var itemList = items.ToList(); return contributionWeight is > 0 and <= 100 && passScore is >= 0 and <= 100 && itemList.Count > 0 && itemList.All(item => item.Weight is > 0 and <= 100) && itemList.Sum(item => item.Weight) == 100; } public static decimal? CalculateTotal( ExperimentGradeRecord record, IReadOnlyCollection items) { if (record.SafetyViolation || record.ParticipationStatus == ExperimentParticipationStatus.Absent) return 0; if (record.ParticipationStatus is ExperimentParticipationStatus.Pending or ExperimentParticipationStatus.Excused or ExperimentParticipationStatus.Exempt) return null; var scores = record.ItemScores.ToDictionary( x => x.ExperimentGradeItemId); decimal total = 0; foreach (var item in items) { if (!scores.TryGetValue(item.Id, out var score) || !score.Score.HasValue) return null; total += score.Score.Value * item.Weight / 100; } return Math.Round(total, 1, MidpointRounding.AwayFromZero); } }