1
0

Optimize grade average provider (#792)

This commit is contained in:
Mikołaj Pich
2020-05-10 10:51:01 +02:00
committed by GitHub
parent 8eb0c0351b
commit 6d1fa0cf05
19 changed files with 278 additions and 324 deletions

View File

@ -1,14 +1,19 @@
package io.github.wulkanowy.data.repositories.grade
import io.github.wulkanowy.data.db.dao.GradeDao
import io.github.wulkanowy.data.db.dao.GradeSummaryDao
import io.github.wulkanowy.data.db.entities.Grade
import io.github.wulkanowy.data.db.entities.GradeSummary
import io.github.wulkanowy.data.db.entities.Semester
import io.reactivex.Maybe
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class GradeLocal @Inject constructor(private val gradeDb: GradeDao) {
class GradeLocal @Inject constructor(
private val gradeDb: GradeDao,
private val gradeSummaryDb: GradeSummaryDao
) {
fun saveGrades(grades: List<Grade>) {
gradeDb.insertAll(grades)
@ -22,7 +27,19 @@ class GradeLocal @Inject constructor(private val gradeDb: GradeDao) {
gradeDb.updateAll(grades)
}
fun getGrades(semester: Semester): Maybe<List<Grade>> {
fun getGradesDetails(semester: Semester): Maybe<List<Grade>> {
return gradeDb.loadAll(semester.semesterId, semester.studentId).filter { it.isNotEmpty() }
}
fun saveGradesSummary(gradesSummary: List<GradeSummary>) {
gradeSummaryDb.insertAll(gradesSummary)
}
fun deleteGradesSummary(gradesSummary: List<GradeSummary>) {
gradeSummaryDb.deleteAll(gradesSummary)
}
fun getGradesSummary(semester: Semester): Maybe<List<GradeSummary>> {
return gradeSummaryDb.loadAll(semester.semesterId, semester.studentId).filter { it.isNotEmpty() }
}
}

View File

@ -1,6 +1,7 @@
package io.github.wulkanowy.data.repositories.grade
import io.github.wulkanowy.data.db.entities.Grade
import io.github.wulkanowy.data.db.entities.GradeSummary
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.sdk.Sdk
@ -12,11 +13,11 @@ import javax.inject.Singleton
@Singleton
class GradeRemote @Inject constructor(private val sdk: Sdk) {
fun getGrades(student: Student, semester: Semester): Single<List<Grade>> {
fun getGrades(student: Student, semester: Semester): Single<Pair<List<Grade>, List<GradeSummary>>> {
return sdk.init(student).switchDiary(semester.diaryId, semester.schoolYear)
.getGrades(semester.semesterId)
.map { grades ->
grades.map {
.map { (details, summary) ->
details.map {
Grade(
studentId = semester.studentId,
semesterId = semester.semesterId,
@ -33,6 +34,19 @@ class GradeRemote @Inject constructor(private val sdk: Sdk) {
date = it.date,
teacher = it.teacher
)
} to summary.map {
GradeSummary(
semesterId = semester.semesterId,
studentId = semester.studentId,
position = 0,
subject = it.name,
predictedGrade = it.predicted,
finalGrade = it.final,
pointsSum = it.pointsSum,
proposedPoints = it.proposedPoints,
finalPoints = it.finalPoints,
average = it.average
)
}
}
}

View File

@ -3,6 +3,7 @@ package io.github.wulkanowy.data.repositories.grade
import com.github.pwittchen.reactivenetwork.library.rx2.ReactiveNetwork
import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.InternetObservingSettings
import io.github.wulkanowy.data.db.entities.Grade
import io.github.wulkanowy.data.db.entities.GradeSummary
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.utils.uniqueSubtract
@ -19,34 +20,47 @@ class GradeRepository @Inject constructor(
private val remote: GradeRemote
) {
fun getGrades(student: Student, semester: Semester, forceRefresh: Boolean = false, notify: Boolean = false): Single<List<Grade>> {
return local.getGrades(semester).filter { !forceRefresh }
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
.flatMap {
if (it) remote.getGrades(student, semester)
else Single.error(UnknownHostException())
}.flatMap { new ->
local.getGrades(semester).toSingle(emptyList())
.doOnSuccess { old ->
val notifyBreakDate = old.maxBy { it.date }?.date ?: student.registrationDate.toLocalDate()
local.deleteGrades(old.uniqueSubtract(new))
local.saveGrades(new.uniqueSubtract(old)
.onEach {
if (it.date >= notifyBreakDate) it.apply {
isRead = false
if (notify) isNotified = false
}
})
}
}.flatMap { local.getGrades(semester).toSingle(emptyList()) })
fun getGrades(student: Student, semester: Semester, forceRefresh: Boolean = false, notify: Boolean = false): Single<Pair<List<Grade>, List<GradeSummary>>> {
return local.getGradesDetails(semester).flatMap { details ->
local.getGradesSummary(semester).map { summary -> details to summary }
}.filter { !forceRefresh }
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings).flatMap {
if (it) remote.getGrades(student, semester)
else Single.error(UnknownHostException())
}.flatMap { (newDetails, newSummary) ->
local.getGradesDetails(semester).toSingle(emptyList())
.doOnSuccess { old ->
val notifyBreakDate = old.maxBy { it.date }?.date ?: student.registrationDate.toLocalDate()
local.deleteGrades(old.uniqueSubtract(newDetails))
local.saveGrades(newDetails.uniqueSubtract(old)
.onEach {
if (it.date >= notifyBreakDate) it.apply {
isRead = false
if (notify) isNotified = false
}
})
}.flatMap {
local.getGradesSummary(semester).toSingle(emptyList())
.doOnSuccess { old ->
local.deleteGradesSummary(old.uniqueSubtract(newSummary))
local.saveGradesSummary(newSummary.uniqueSubtract(old))
}
}
}.flatMap {
local.getGradesDetails(semester).toSingle(emptyList()).flatMap { details ->
local.getGradesSummary(semester).toSingle(emptyList()).map { summary ->
details to summary
}
}
})
}
fun getUnreadGrades(semester: Semester): Single<List<Grade>> {
return local.getGrades(semester).map { it.filter { grade -> !grade.isRead } }.toSingle(emptyList())
return local.getGradesDetails(semester).map { it.filter { grade -> !grade.isRead } }.toSingle(emptyList())
}
fun getNotNotifiedGrades(semester: Semester): Single<List<Grade>> {
return local.getGrades(semester).map { it.filter { grade -> !grade.isNotified } }.toSingle(emptyList())
return local.getGradesDetails(semester).map { it.filter { grade -> !grade.isNotified } }.toSingle(emptyList())
}
fun updateGrade(grade: Grade): Completable {

View File

@ -1,24 +0,0 @@
package io.github.wulkanowy.data.repositories.gradessummary
import io.github.wulkanowy.data.db.dao.GradeSummaryDao
import io.github.wulkanowy.data.db.entities.GradeSummary
import io.github.wulkanowy.data.db.entities.Semester
import io.reactivex.Maybe
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class GradeSummaryLocal @Inject constructor(private val gradeSummaryDb: GradeSummaryDao) {
fun saveGradesSummary(gradesSummary: List<GradeSummary>) {
gradeSummaryDb.insertAll(gradesSummary)
}
fun deleteGradesSummary(gradesSummary: List<GradeSummary>) {
gradeSummaryDb.deleteAll(gradesSummary)
}
fun getGradesSummary(semester: Semester): Maybe<List<GradeSummary>> {
return gradeSummaryDb.loadAll(semester.semesterId, semester.studentId).filter { it.isNotEmpty() }
}
}

View File

@ -1,35 +0,0 @@
package io.github.wulkanowy.data.repositories.gradessummary
import io.github.wulkanowy.data.db.entities.GradeSummary
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.sdk.Sdk
import io.github.wulkanowy.utils.init
import io.reactivex.Single
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class GradeSummaryRemote @Inject constructor(private val sdk: Sdk) {
fun getGradeSummary(student: Student, semester: Semester): Single<List<GradeSummary>> {
return sdk.init(student).switchDiary(semester.diaryId, semester.schoolYear)
.getGradesSummary(semester.semesterId)
.map { gradesSummary ->
gradesSummary.map {
GradeSummary(
semesterId = semester.semesterId,
studentId = semester.studentId,
position = 0,
subject = it.name,
predictedGrade = it.predicted,
finalGrade = it.final,
pointsSum = it.pointsSum,
proposedPoints = it.proposedPoints,
finalPoints = it.finalPoints,
average = it.average
)
}
}
}
}

View File

@ -1,35 +0,0 @@
package io.github.wulkanowy.data.repositories.gradessummary
import com.github.pwittchen.reactivenetwork.library.rx2.ReactiveNetwork
import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.InternetObservingSettings
import io.github.wulkanowy.data.db.entities.GradeSummary
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.utils.uniqueSubtract
import io.reactivex.Single
import java.net.UnknownHostException
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class GradeSummaryRepository @Inject constructor(
private val settings: InternetObservingSettings,
private val local: GradeSummaryLocal,
private val remote: GradeSummaryRemote
) {
fun getGradesSummary(student: Student, semester: Semester, forceRefresh: Boolean = false): Single<List<GradeSummary>> {
return local.getGradesSummary(semester).filter { !forceRefresh }
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
.flatMap {
if (it) remote.getGradeSummary(student, semester)
else Single.error(UnknownHostException())
}.flatMap { new ->
local.getGradesSummary(semester).toSingle(emptyList())
.doOnSuccess { old ->
local.deleteGradesSummary(old.uniqueSubtract(new))
local.saveGradesSummary(new.uniqueSubtract(old))
}
}.flatMap { local.getGradesSummary(semester).toSingle(emptyList()) })
}
}

View File

@ -21,7 +21,6 @@ import io.github.wulkanowy.services.sync.works.AttendanceWork
import io.github.wulkanowy.services.sync.works.CompletedLessonWork
import io.github.wulkanowy.services.sync.works.ExamWork
import io.github.wulkanowy.services.sync.works.GradeStatisticsWork
import io.github.wulkanowy.services.sync.works.GradeSummaryWork
import io.github.wulkanowy.services.sync.works.GradeWork
import io.github.wulkanowy.services.sync.works.HomeworkWork
import io.github.wulkanowy.services.sync.works.LuckyNumberWork
@ -64,10 +63,6 @@ abstract class ServicesModule {
@IntoSet
abstract fun provideAttendanceWork(work: AttendanceWork): Work
@Binds
@IntoSet
abstract fun provideGradeSummaryWork(work: GradeSummaryWork): Work
@Binds
@IntoSet
abstract fun provideExamWork(work: ExamWork): Work

View File

@ -1,14 +0,0 @@
package io.github.wulkanowy.services.sync.works
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.data.repositories.gradessummary.GradeSummaryRepository
import io.reactivex.Completable
import javax.inject.Inject
class GradeSummaryWork @Inject constructor(private val gradeSummaryRepository: GradeSummaryRepository) : Work {
override fun create(student: Student, semester: Semester): Completable {
return gradeSummaryRepository.getGradesSummary(student, semester, true).ignoreElement()
}
}

View File

@ -58,4 +58,3 @@ class GradeWork @Inject constructor(
)
}
}

View File

@ -3,71 +3,76 @@ package io.github.wulkanowy.ui.modules.grade
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.data.repositories.grade.GradeRepository
import io.github.wulkanowy.data.repositories.gradessummary.GradeSummaryRepository
import io.github.wulkanowy.data.repositories.preferences.PreferencesRepository
import io.github.wulkanowy.data.repositories.semester.SemesterRepository
import io.github.wulkanowy.sdk.Sdk
import io.github.wulkanowy.utils.calcAverage
import io.github.wulkanowy.utils.changeModifier
import io.reactivex.Maybe
import io.reactivex.Single
import javax.inject.Inject
class GradeAverageProvider @Inject constructor(
private val preferencesRepository: PreferencesRepository,
private val semesterRepository: SemesterRepository,
private val gradeRepository: GradeRepository,
private val gradeSummaryRepository: GradeSummaryRepository
private val preferencesRepository: PreferencesRepository
) {
private val plusModifier = preferencesRepository.gradePlusModifier
private val minusModifier = preferencesRepository.gradeMinusModifier
fun getGradeAverage(student: Student, semesters: List<Semester>, selectedSemesterId: Int, forceRefresh: Boolean): Single<List<Triple<String, Double, String>>> {
return when (preferencesRepository.gradeAverageMode) {
"all_year" -> getAllYearAverage(student, semesters, selectedSemesterId, forceRefresh)
"only_one_semester" -> getOnlyOneSemesterAverage(student, semesters, selectedSemesterId, forceRefresh)
else -> throw IllegalArgumentException("Incorrect grade average mode: ${preferencesRepository.gradeAverageMode} ")
fun getGradesDetailsWithAverage(student: Student, semesterId: Int, forceRefresh: Boolean = false): Single<List<GradeDetailsWithAverage>> {
return semesterRepository.getSemesters(student).flatMap { semesters ->
when (preferencesRepository.gradeAverageMode) {
"only_one_semester" -> getSemesterDetailsWithAverage(student, semesters.single { it.semesterId == semesterId }, forceRefresh)
"all_year" -> calculateWholeYearAverage(student, semesters, semesterId, forceRefresh)
else -> throw IllegalArgumentException("Incorrect grade average mode: ${preferencesRepository.gradeAverageMode} ")
}
}
}
private fun getAllYearAverage(student: Student, semesters: List<Semester>, semesterId: Int, forceRefresh: Boolean): Single<List<Triple<String, Double, String>>> {
private fun calculateWholeYearAverage(student: Student, semesters: List<Semester>, semesterId: Int, forceRefresh: Boolean): Single<List<GradeDetailsWithAverage>> {
val selectedSemester = semesters.single { it.semesterId == semesterId }
val firstSemester = semesters.single { it.diaryId == selectedSemester.diaryId && it.semesterName == 1 }
return getAverageFromGradeSummary(student, selectedSemester, forceRefresh)
.switchIfEmpty(gradeRepository.getGrades(student, selectedSemester, forceRefresh)
.flatMap { firstGrades ->
if (selectedSemester == firstSemester) Single.just(firstGrades)
else {
gradeRepository.getGrades(student, firstSemester)
.map { secondGrades -> secondGrades + firstGrades }
return getSemesterDetailsWithAverage(student, selectedSemester, forceRefresh).flatMap { selectedDetails ->
val isAnyAverage = selectedDetails.any { it.average != .0 }
if (selectedSemester != firstSemester) {
getSemesterDetailsWithAverage(student, firstSemester, forceRefresh).map { secondDetails ->
selectedDetails.map { selected ->
val second = secondDetails.singleOrNull { it.subject == selected.subject }
selected.copy(
average = if (!isAnyAverage || preferencesRepository.gradeAverageForceCalc) {
(selected.grades + second?.grades.orEmpty()).calcAverage()
} else (selected.average + (second?.average ?: selected.average)) / 2
)
}
}.map { grades ->
grades.map { if (student.loginMode == Sdk.Mode.SCRAPPER.name) it.changeModifier(plusModifier, minusModifier) else it }
.groupBy { it.subject }
.map { Triple(it.key, it.value.calcAverage(), "") }
})
}
} else Single.just(selectedDetails)
}
}
private fun getOnlyOneSemesterAverage(student: Student, semesters: List<Semester>, semesterId: Int, forceRefresh: Boolean): Single<List<Triple<String, Double, String>>> {
val selectedSemester = semesters.single { it.semesterId == semesterId }
private fun getSemesterDetailsWithAverage(student: Student, semester: Semester, forceRefresh: Boolean): Single<List<GradeDetailsWithAverage>> {
return gradeRepository.getGrades(student, semester, forceRefresh).map { (details, summaries) ->
val isAnyAverage = summaries.any { it.average != .0 }
val allGrades = details.groupBy { it.subject }
return getAverageFromGradeSummary(student, selectedSemester, forceRefresh)
.switchIfEmpty(gradeRepository.getGrades(student, selectedSemester, forceRefresh)
.map { grades ->
grades.map { if (student.loginMode == Sdk.Mode.SCRAPPER.name) it.changeModifier(plusModifier, minusModifier) else it }
.groupBy { it.subject }
.map { Triple(it.key, it.value.calcAverage(), "") }
})
}
private fun getAverageFromGradeSummary(student: Student, selectedSemester: Semester, forceRefresh: Boolean): Maybe<List<Triple<String, Double, String>>> {
return gradeSummaryRepository.getGradesSummary(student, selectedSemester, forceRefresh)
.toMaybe()
.flatMap {
if (it.any { summary -> summary.average != .0 }) {
Maybe.just(it.map { summary -> Triple(summary.subject, summary.average, summary.pointsSum) })
} else Maybe.empty()
}.filter { !preferencesRepository.gradeAverageForceCalc }
summaries.map { summary ->
val grades = allGrades[summary.subject].orEmpty()
GradeDetailsWithAverage(
subject = summary.subject,
average = if (!isAnyAverage || preferencesRepository.gradeAverageForceCalc) {
grades.map {
if (student.loginMode == Sdk.Mode.SCRAPPER.name) it.changeModifier(plusModifier, minusModifier)
else it
}.calcAverage()
} else summary.average,
points = summary.pointsSum,
summary = summary,
grades = grades
)
}
}
}
}

View File

@ -0,0 +1,12 @@
package io.github.wulkanowy.ui.modules.grade
import io.github.wulkanowy.data.db.entities.Grade
import io.github.wulkanowy.data.db.entities.GradeSummary
data class GradeDetailsWithAverage(
val subject: String,
val average: Double,
val points: String,
val summary: GradeSummary,
val grades: List<Grade>
)

View File

@ -107,7 +107,7 @@ class GradeDetailsAdapter @Inject constructor() : BaseExpandableAdapter<Recycler
gradeHeaderAverage.text = formatAverage(header.average, root.context.resources)
gradeHeaderPointsSum.text = root.context.getString(R.string.grade_points_sum, header.pointsSum)
gradeHeaderPointsSum.visibility = if (!header.pointsSum.isNullOrEmpty()) View.VISIBLE else View.GONE
gradeHeaderNumber.text = root.context.resources.getQuantityString(R.plurals.grade_number_item, header.number, header.number)
gradeHeaderNumber.text = root.context.resources.getQuantityString(R.plurals.grade_number_item, header.grades.size, header.grades.size)
gradeHeaderNote.visibility = if (header.newGrades > 0) View.VISIBLE else View.GONE
if (header.newGrades > 0) gradeHeaderNote.text = header.newGrades.toString(10)

View File

@ -12,7 +12,6 @@ data class GradeDetailsItem(
data class GradeDetailsHeader(
val subject: String,
val number: Int,
val average: Double?,
val pointsSum: String?,
var newGrades: Int,

View File

@ -8,6 +8,7 @@ import io.github.wulkanowy.data.repositories.student.StudentRepository
import io.github.wulkanowy.ui.base.BasePresenter
import io.github.wulkanowy.ui.base.ErrorHandler
import io.github.wulkanowy.ui.modules.grade.GradeAverageProvider
import io.github.wulkanowy.ui.modules.grade.GradeDetailsWithAverage
import io.github.wulkanowy.utils.FirebaseAnalyticsHelper
import io.github.wulkanowy.utils.SchedulersProvider
import timber.log.Timber
@ -126,14 +127,7 @@ class GradeDetailsPresenter @Inject constructor(
private fun loadData(semesterId: Int, forceRefresh: Boolean) {
Timber.i("Loading grade details data started")
disposable.add(studentRepository.getCurrentStudent()
.flatMap { semesterRepository.getSemesters(it).map { semester -> it to semester } }
.flatMap { (student, semesters) ->
averageProvider.getGradeAverage(student, semesters, semesterId, forceRefresh).flatMap { averages ->
gradeRepository.getGrades(student, semesters.first { it.semesterId == semesterId }, forceRefresh)
.map { it.sortedByDescending { grade -> grade.date } }
.map { createGradeItems(it, averages) }
}
}
.flatMap { averageProvider.getGradesDetailsWithAverage(it, semesterId, forceRefresh) }
.subscribeOn(schedulers.backgroundThread)
.observeOn(schedulers.mainThread)
.doFinally {
@ -146,16 +140,14 @@ class GradeDetailsPresenter @Inject constructor(
}
.subscribe({ grades ->
Timber.i("Loading grade details result: Success")
newGradesAmount = grades
.filter { it.viewType == ViewType.HEADER }
.sumBy { item -> (item.value as GradeDetailsHeader).newGrades }
newGradesAmount = grades.sumBy { it.grades.sumBy { grade -> if (!grade.isRead) 1 else 0 } }
updateMarkAsDoneButton()
view?.run {
showEmpty(grades.isEmpty())
showErrorView(false)
showContent(grades.isNotEmpty())
updateData(
data = grades,
data = createGradeItems(grades),
isGradeExpandable = preferencesRepository.isGradeExpandable,
gradeColorTheme = preferencesRepository.gradeColorTheme
)
@ -178,17 +170,16 @@ class GradeDetailsPresenter @Inject constructor(
}
}
private fun createGradeItems(items: List<Grade>, averages: List<Triple<String, Double, String>>): List<GradeDetailsItem> {
return items.groupBy { grade -> grade.subject }.toSortedMap().map { (subject, grades) ->
private fun createGradeItems(items: List<GradeDetailsWithAverage>): List<GradeDetailsItem> {
return items.filter { it.grades.isNotEmpty() }.map { (subject, average, points, _, grades) ->
val subItems = grades.map {
GradeDetailsItem(it, ViewType.ITEM)
}
listOf(GradeDetailsItem(GradeDetailsHeader(
subject = subject,
average = averages.singleOrNull { subject == it.first }?.second,
pointsSum = averages.singleOrNull { subject == it.first }?.third,
number = grades.size,
average = average,
pointsSum = points,
newGrades = grades.filter { grade -> !grade.isRead }.size,
grades = subItems
), ViewType.HEADER)) + if (preferencesRepository.isGradeExpandable) emptyList() else subItems

View File

@ -1,12 +1,11 @@
package io.github.wulkanowy.ui.modules.grade.summary
import io.github.wulkanowy.data.db.entities.GradeSummary
import io.github.wulkanowy.data.repositories.gradessummary.GradeSummaryRepository
import io.github.wulkanowy.data.repositories.semester.SemesterRepository
import io.github.wulkanowy.data.repositories.student.StudentRepository
import io.github.wulkanowy.ui.base.BasePresenter
import io.github.wulkanowy.ui.base.ErrorHandler
import io.github.wulkanowy.ui.modules.grade.GradeAverageProvider
import io.github.wulkanowy.ui.modules.grade.GradeDetailsWithAverage
import io.github.wulkanowy.utils.FirebaseAnalyticsHelper
import io.github.wulkanowy.utils.SchedulersProvider
import timber.log.Timber
@ -16,8 +15,6 @@ class GradeSummaryPresenter @Inject constructor(
schedulers: SchedulersProvider,
errorHandler: ErrorHandler,
studentRepository: StudentRepository,
private val gradeSummaryRepository: GradeSummaryRepository,
private val semesterRepository: SemesterRepository,
private val averageProvider: GradeAverageProvider,
private val analytics: FirebaseAnalyticsHelper
) : BasePresenter<GradeSummaryView>(errorHandler, studentRepository, schedulers) {
@ -33,15 +30,8 @@ class GradeSummaryPresenter @Inject constructor(
fun onParentViewLoadData(semesterId: Int, forceRefresh: Boolean) {
Timber.i("Loading grade summary data started")
disposable.add(studentRepository.getCurrentStudent()
.flatMap { semesterRepository.getSemesters(it).map { semesters -> it to semesters } }
.flatMap { (student, semesters) ->
gradeSummaryRepository.getGradesSummary(student, semesters.first { it.semesterId == semesterId }, forceRefresh)
.map { it.sortedBy { subject -> subject.subject } }
.flatMap { gradesSummary ->
averageProvider.getGradeAverage(student, semesters, semesterId, forceRefresh)
.map { averages -> createGradeSummaryItems(gradesSummary, averages) }
}
}
.flatMap { averageProvider.getGradesDetailsWithAverage(it, semesterId, forceRefresh) }
.map { createGradeSummaryItems(it) }
.subscribeOn(schedulers.backgroundThread)
.observeOn(schedulers.mainThread)
.doFinally {
@ -112,12 +102,10 @@ class GradeSummaryPresenter @Inject constructor(
disposable.clear()
}
private fun createGradeSummaryItems(gradesSummary: List<GradeSummary>, averages: List<Triple<String, Double, String>>): List<GradeSummary> {
return gradesSummary
.filter { !checkEmpty(it, averages) }
.map { gradeSummary ->
gradeSummary.copy(average = averages.singleOrNull { gradeSummary.subject == it.first }?.second ?: .0)
}
private fun createGradeSummaryItems(items: List<GradeDetailsWithAverage>): List<GradeSummary> {
return items.map {
it.summary.copy(average = it.average)
}
}
private fun checkEmpty(gradeSummary: GradeSummary, averages: List<Triple<String, Double, String>>): Boolean {