Optimize grade average provider (#792)
This commit is contained in:
@ -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() }
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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() }
|
||||
}
|
||||
}
|
@ -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
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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()) })
|
||||
}
|
||||
}
|
@ -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
|
||||
|
@ -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()
|
||||
}
|
||||
}
|
@ -58,4 +58,3 @@ class GradeWork @Inject constructor(
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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>
|
||||
)
|
@ -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)
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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 {
|
||||
|
Reference in New Issue
Block a user