forked from firka/firka
@@ -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<Grade> sortedGrades) {
|
||||
double calculateAverage(List<Grade> 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;
|
||||
|
||||
@@ -108,11 +108,46 @@ class _HomeGradesScreen extends FirkaState<HomeGradesScreen> {
|
||||
var subjectAvg = 0.00;
|
||||
var subjectCount = 0;
|
||||
var subjectAvgRounded = 0.00;
|
||||
final summaryAvg2 = calculateAverage(grades!.response!);
|
||||
final allGrades = grades!.response!;
|
||||
final bySubject = <String, List<Grade>>{};
|
||||
for (final g in allGrades) {
|
||||
bySubject.putIfAbsent(g.subject.uid, () => []).add(g);
|
||||
}
|
||||
final gradesForCalculation = <Grade>[];
|
||||
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<Subject> subjects = List<Subject>.empty(growable: true);
|
||||
final List<Widget> 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<HomeGradesScreen> {
|
||||
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<HomeGradesScreen> {
|
||||
} 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<HomeGradesScreen> {
|
||||
),
|
||||
],
|
||||
),
|
||||
GradeChartWithInteraction(grades: grades?.response ?? []),
|
||||
GradeChartWithInteraction(grades: gradesForCalculation),
|
||||
SizedBox(height: 2),
|
||||
GradeSummaryBar(
|
||||
grades: grades?.response ?? [],
|
||||
grades: gradesForCalculation,
|
||||
l10n: widget.data.l10n,
|
||||
),
|
||||
SizedBox(height: 12),
|
||||
|
||||
@@ -94,37 +94,47 @@ Color getGradeColor(
|
||||
|
||||
extension GradeListExtension on List<Grade> {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user