diff --git a/firka/lib/core/average_helper.dart b/firka/lib/core/average_helper.dart index ff37068..58cdc0f 100644 --- a/firka/lib/core/average_helper.dart +++ b/firka/lib/core/average_helper.dart @@ -5,7 +5,7 @@ bool _isPercentageGrade(Grade grade) { return name.contains('szazalek') || name.contains('percent'); } -bool _shouldIgnoreInAverage(Grade grade) { +bool shouldIgnoreInAverage(Grade grade) { if (_isPercentageGrade(grade)) { return true; } @@ -19,12 +19,24 @@ bool _shouldIgnoreInAverage(Grade grade) { return false; } -double calculateAverage(List sortedGrades) { +double calculateAverage(List sortedGrades, {bool applyIgnoreFilter = true}) { double totalWeight = 0.0; double weightedSum = 0.0; + if (applyIgnoreFilter && + sortedGrades.isNotEmpty && + sortedGrades.where((g) => !shouldIgnoreInAverage(g)).isEmpty) { + final grades = sortedGrades.where( + (g) => g.numericValue != null && g.numericValue! > 0, + ); + + if (grades.isNotEmpty) { + return grades.last.numericValue!.toDouble(); + } + } + for (final grade in sortedGrades) { - if (_shouldIgnoreInAverage(grade)) continue; + if (applyIgnoreFilter && shouldIgnoreInAverage(grade)) continue; final value = grade.numericValue; final weight = grade.weightPercentage; diff --git a/firka/lib/ui/phone/pages/home/home_grades.dart b/firka/lib/ui/phone/pages/home/home_grades.dart index f3625a4..82a3b20 100644 --- a/firka/lib/ui/phone/pages/home/home_grades.dart +++ b/firka/lib/ui/phone/pages/home/home_grades.dart @@ -108,11 +108,46 @@ class _HomeGradesScreen extends FirkaState { var subjectAvg = 0.00; var subjectCount = 0; var subjectAvgRounded = 0.00; - final summaryAvg2 = calculateAverage(grades!.response!); + final allGrades = grades!.response!; + final bySubject = >{}; + for (final g in allGrades) { + bySubject.putIfAbsent(g.subject.uid, () => []).add(g); + } + final gradesForCalculation = []; + for (final subjectGrades in bySubject.values) { + final feleviOrEvvegi = subjectGrades.where((g) { + final typeName = g.type.name?.toLowerCase() ?? ''; + return typeName == 'felevi_jegy_ertekeles' || + typeName == 'evvegi_jegy_ertekeles'; + }).toList(); + final hasOtherType = subjectGrades.any((g) { + final typeName = g.type.name?.toLowerCase() ?? ''; + return typeName != 'felevi_jegy_ertekeles' && + typeName != 'evvegi_jegy_ertekeles'; + }); + if (!hasOtherType && feleviOrEvvegi.isNotEmpty) { + final withValue = feleviOrEvvegi + .where((g) => g.numericValue != null && g.numericValue! > 0) + .toList(); + if (withValue.isNotEmpty) { + withValue.sort((a, b) => a.recordDate.compareTo(b.recordDate)); + gradesForCalculation.add(withValue.last); + } + } else { + gradesForCalculation.addAll( + subjectGrades.where((g) => !shouldIgnoreInAverage(g)), + ); + } + } + + final summaryAvg2 = calculateAverage( + gradesForCalculation, + applyIgnoreFilter: false, + ); final List subjects = List.empty(growable: true); final List gradeCards = []; - for (var grade in grades!.response!) { + for (var grade in allGrades) { if (subjects.where((s) => s.uid == grade.subject.uid).isEmpty) { subjects.add(grade.subject); } @@ -140,19 +175,39 @@ class _HomeGradesScreen extends FirkaState { subjects.sort((s1, s2) => s1.name.compareTo(s2.name)); for (var subject in subjects) { - final subjectGrades = grades!.response! + final subjectGrades = allGrades .where((g) => g.subject.uid == subject.uid) .toList(); double avg = double.nan; if (subjectGrades.isNotEmpty) { - avg = subjectGrades.getAverageBySubject(subject); + final feleviOrEvvegi = subjectGrades.where((g) { + final typeName = g.type.name?.toLowerCase() ?? ''; + return typeName == 'felevi_jegy_ertekeles' || + typeName == 'evvegi_jegy_ertekeles'; + }).toList(); + final hasOtherType = subjectGrades.any((g) { + final typeName = g.type.name?.toLowerCase() ?? ''; + return typeName != 'felevi_jegy_ertekeles' && + typeName != 'evvegi_jegy_ertekeles'; + }); + if (!hasOtherType && feleviOrEvvegi.isNotEmpty) { + final withValue = feleviOrEvvegi + .where((g) => g.numericValue != null && g.numericValue! > 0) + .toList(); + if (withValue.isNotEmpty) { + withValue.sort((a, b) => a.recordDate.compareTo(b.recordDate)); + avg = withValue.last.numericValue!.toDouble(); + } + } else { + avg = subjectGrades.getAverageBySubject(subject); + } } if (avg.isNaN) { gradeCards.add( GestureDetector( - child: GradeSmallCard(grades!.response!, subject), + child: GradeSmallCard(allGrades, subject), onTap: () { activeSubjectUid = subject.uid; subjectName = subject.name; @@ -168,7 +223,7 @@ class _HomeGradesScreen extends FirkaState { } else { gradeCards.add( GestureDetector( - child: GradeSmallCard(grades!.response!, subject), + child: GradeSmallCard(allGrades, subject), onTap: () { activeSubjectUid = subject.uid; subjectName = subject.name; @@ -235,10 +290,10 @@ class _HomeGradesScreen extends FirkaState { ), ], ), - GradeChartWithInteraction(grades: grades?.response ?? []), + GradeChartWithInteraction(grades: gradesForCalculation), SizedBox(height: 2), GradeSummaryBar( - grades: grades?.response ?? [], + grades: gradesForCalculation, l10n: widget.data.l10n, ), SizedBox(height: 12), diff --git a/firka_common/lib/ui/components/grade_helpers.dart b/firka_common/lib/ui/components/grade_helpers.dart index f66b5f5..ac65325 100644 --- a/firka_common/lib/ui/components/grade_helpers.dart +++ b/firka_common/lib/ui/components/grade_helpers.dart @@ -94,37 +94,47 @@ Color getGradeColor( extension GradeListExtension on List { double getAverageBySubject(Subject subject) { + final subjectGrades = where((g) => g.subject.uid == subject.uid).toList(); + if (subjectGrades.isEmpty) return double.nan; + + final feleviOrEvvegi = subjectGrades.where((g) { + final typeName = g.type.name?.toLowerCase() ?? ''; + return typeName == 'felevi_jegy_ertekeles' || + typeName == 'evvegi_jegy_ertekeles'; + }).toList(); + final hasOtherType = subjectGrades.any((g) { + final typeName = g.type.name?.toLowerCase() ?? ''; + return typeName != 'felevi_jegy_ertekeles' && + typeName != 'evvegi_jegy_ertekeles'; + }); + + if (!hasOtherType && feleviOrEvvegi.isNotEmpty) { + final withValue = feleviOrEvvegi + .where((g) => g.numericValue != null && g.numericValue! > 0) + .toList(); + if (withValue.isEmpty) return double.nan; + withValue.sort((a, b) => a.recordDate.compareTo(b.recordDate)); + return withValue.last.numericValue!.toDouble(); + } + var weightTotal = 0.00; var sum = 0.00; - - for (var grade in this) { - if (grade.subject.uid == subject.uid) { - final valueTypeName = grade.valueType.name?.toLowerCase() ?? ''; - final isPercentage = - valueTypeName.contains('szazalek') || - valueTypeName.contains('percent'); - - final typeName = grade.type.name?.toLowerCase() ?? ''; - final isHalfYear = typeName == 'felevi_jegy_ertekeles'; - final isEndYear = typeName == 'evvegi_jegy_ertekeles'; - - if (isPercentage || isHalfYear || isEndYear) { - continue; - } - - if (grade.numericValue != null) { - var weight = (grade.weightPercentage ?? 100) / 100.0; - weightTotal += weight; - - sum += grade.numericValue! * weight; - } + for (var grade in subjectGrades) { + final valueTypeName = grade.valueType.name?.toLowerCase() ?? ''; + final isPercentage = + valueTypeName.contains('szazalek') || + valueTypeName.contains('percent'); + final typeName = grade.type.name?.toLowerCase() ?? ''; + final isHalfYear = typeName == 'felevi_jegy_ertekeles'; + final isEndYear = typeName == 'evvegi_jegy_ertekeles'; + if (isPercentage || isHalfYear || isEndYear) continue; + if (grade.numericValue != null) { + var weight = (grade.weightPercentage ?? 100) / 100.0; + weightTotal += weight; + sum += grade.numericValue! * weight; } } - - if (weightTotal == 0) { - return double.nan; - } - + if (weightTotal == 0) return double.nan; return sum / weightTotal; } }