mirror of
https://github.com/wulkanowy/wulkanowy.git
synced 2024-11-22 11:06:05 -06:00
Add average in class grades statistics (#1017)
This commit is contained in:
parent
ada5854d10
commit
a1ebf6c6ad
@ -142,7 +142,7 @@ configurations.all {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation "io.github.wulkanowy:sdk:0.22.2"
|
||||
implementation "io.github.wulkanowy:sdk:bcf6b53"
|
||||
|
||||
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.0.10'
|
||||
|
||||
|
1898
app/schemas/io.github.wulkanowy.data.db.AppDatabase/29.json
Normal file
1898
app/schemas/io.github.wulkanowy.data.db.AppDatabase/29.json
Normal file
File diff suppressed because it is too large
Load Diff
@ -4,8 +4,8 @@ import androidx.room.Room
|
||||
import androidx.test.core.app.ApplicationProvider
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import io.github.wulkanowy.data.db.AppDatabase
|
||||
import io.github.wulkanowy.data.db.entities.GradePartialStatistics
|
||||
import io.github.wulkanowy.data.db.entities.GradePointsStatistics
|
||||
import io.github.wulkanowy.data.db.entities.GradeStatistics
|
||||
import io.github.wulkanowy.data.db.entities.Semester
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.runBlocking
|
||||
@ -27,7 +27,7 @@ class GradeStatisticsLocalTest {
|
||||
fun createDb() {
|
||||
testDb = Room.inMemoryDatabaseBuilder(ApplicationProvider.getApplicationContext(), AppDatabase::class.java)
|
||||
.build()
|
||||
gradeStatisticsLocal = GradeStatisticsLocal(testDb.gradeStatistics, testDb.gradePointsStatistics)
|
||||
gradeStatisticsLocal = GradeStatisticsLocal(testDb.gradePartialStatisticsDao, testDb.gradePointsStatisticsDao, testDb.gradeSemesterStatisticsDao)
|
||||
}
|
||||
|
||||
@After
|
||||
@ -41,9 +41,9 @@ class GradeStatisticsLocalTest {
|
||||
getGradeStatistics("Matematyka", 2, 1),
|
||||
getGradeStatistics("Fizyka", 1, 2)
|
||||
)
|
||||
runBlocking { gradeStatisticsLocal.saveGradesStatistics(list) }
|
||||
runBlocking { gradeStatisticsLocal.saveGradePartialStatistics(list) }
|
||||
|
||||
val stats = runBlocking { gradeStatisticsLocal.getGradesStatistics(getSemester(), false).first() }
|
||||
val stats = runBlocking { gradeStatisticsLocal.getGradePartialStatistics(getSemester()).first() }
|
||||
assertEquals(1, stats.size)
|
||||
assertEquals(stats[0].subject, "Matematyka")
|
||||
}
|
||||
@ -55,12 +55,10 @@ class GradeStatisticsLocalTest {
|
||||
getGradeStatistics("Chemia", 2, 1),
|
||||
getGradeStatistics("Fizyka", 1, 2)
|
||||
)
|
||||
runBlocking { gradeStatisticsLocal.saveGradesStatistics(list) }
|
||||
runBlocking { gradeStatisticsLocal.saveGradePartialStatistics(list) }
|
||||
|
||||
val stats = runBlocking { gradeStatisticsLocal.getGradesStatistics(getSemester(), false).first() }
|
||||
val stats = runBlocking { gradeStatisticsLocal.getGradePartialStatistics(getSemester()).first() }
|
||||
assertEquals(2, stats.size)
|
||||
// assertEquals(3, stats.size)
|
||||
// assertEquals(stats[0].subject, "Wszystkie") // now in main repo
|
||||
assertEquals(stats[0].subject, "Matematyka")
|
||||
assertEquals(stats[1].subject, "Chemia")
|
||||
}
|
||||
@ -72,9 +70,9 @@ class GradeStatisticsLocalTest {
|
||||
getGradePointsStatistics("Chemia", 2, 1),
|
||||
getGradePointsStatistics("Fizyka", 1, 2)
|
||||
)
|
||||
runBlocking { gradeStatisticsLocal.saveGradesPointsStatistics(list) }
|
||||
runBlocking { gradeStatisticsLocal.saveGradePointsStatistics(list) }
|
||||
|
||||
val stats = runBlocking { gradeStatisticsLocal.getGradesPointsStatistics(getSemester()).first() }
|
||||
val stats = runBlocking { gradeStatisticsLocal.getGradePointsStatistics(getSemester()).first() }
|
||||
with(stats[0]) {
|
||||
assertEquals(subject, "Matematyka")
|
||||
assertEquals(others, 5.0)
|
||||
@ -84,17 +82,17 @@ class GradeStatisticsLocalTest {
|
||||
|
||||
@Test
|
||||
fun saveAndRead_subjectEmpty() {
|
||||
runBlocking { gradeStatisticsLocal.saveGradesPointsStatistics(listOf()) }
|
||||
runBlocking { gradeStatisticsLocal.saveGradePointsStatistics(listOf()) }
|
||||
|
||||
val stats = runBlocking { gradeStatisticsLocal.getGradesPointsStatistics(getSemester()).first() }
|
||||
val stats = runBlocking { gradeStatisticsLocal.getGradePointsStatistics(getSemester()).first() }
|
||||
assertEquals(emptyList(), stats)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun saveAndRead_allEmpty() {
|
||||
runBlocking { gradeStatisticsLocal.saveGradesPointsStatistics(listOf()) }
|
||||
runBlocking { gradeStatisticsLocal.saveGradePointsStatistics(listOf()) }
|
||||
|
||||
val stats = runBlocking { gradeStatisticsLocal.getGradesPointsStatistics(getSemester()).first() }
|
||||
val stats = runBlocking { gradeStatisticsLocal.getGradePointsStatistics(getSemester()).first() }
|
||||
assertEquals(emptyList(), stats)
|
||||
}
|
||||
|
||||
@ -102,8 +100,8 @@ class GradeStatisticsLocalTest {
|
||||
return Semester(2, 2, "", 2019, 1, 2, now(), now(), 1, 1)
|
||||
}
|
||||
|
||||
private fun getGradeStatistics(subject: String, studentId: Int, semesterId: Int): GradeStatistics {
|
||||
return GradeStatistics(studentId, semesterId, subject, 5, 5, false)
|
||||
private fun getGradeStatistics(subject: String, studentId: Int, semesterId: Int): GradePartialStatistics {
|
||||
return GradePartialStatistics(studentId, semesterId, subject, "", "", listOf(5), listOf(5))
|
||||
}
|
||||
|
||||
private fun getGradePointsStatistics(subject: String, studentId: Int, semesterId: Int): GradePointsStatistics {
|
||||
|
@ -42,7 +42,7 @@ class CrashLogExceptionTree : FormatterPriorityTree(Log.ERROR) {
|
||||
connectCrash.setCustomKey("priority", priority)
|
||||
connectCrash.setCustomKey("tag", tag.orEmpty())
|
||||
connectCrash.setCustomKey("message", message)
|
||||
connectCrash.log(priority, t?.stackTraceToString())
|
||||
|
||||
if (t != null) {
|
||||
connectCrash.log(priority, t.stackTraceToString())
|
||||
} else {
|
||||
|
@ -85,11 +85,15 @@ internal class RepositoryModule {
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
fun provideGradeStatisticsDao(database: AppDatabase) = database.gradeStatistics
|
||||
fun provideGradePartialStatisticsDao(database: AppDatabase) = database.gradePartialStatisticsDao
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
fun provideGradePointsStatisticsDao(database: AppDatabase) = database.gradePointsStatistics
|
||||
fun provideGradeSemesterStatisticsDao(database: AppDatabase) = database.gradeSemesterStatisticsDao
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
fun provideGradePointsStatisticsDao(database: AppDatabase) = database.gradePointsStatisticsDao
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
|
@ -13,8 +13,9 @@ import io.github.wulkanowy.data.db.dao.CompletedLessonsDao
|
||||
import io.github.wulkanowy.data.db.dao.ConferenceDao
|
||||
import io.github.wulkanowy.data.db.dao.ExamDao
|
||||
import io.github.wulkanowy.data.db.dao.GradeDao
|
||||
import io.github.wulkanowy.data.db.dao.GradePartialStatisticsDao
|
||||
import io.github.wulkanowy.data.db.dao.GradePointsStatisticsDao
|
||||
import io.github.wulkanowy.data.db.dao.GradeStatisticsDao
|
||||
import io.github.wulkanowy.data.db.dao.GradeSemesterStatisticsDao
|
||||
import io.github.wulkanowy.data.db.dao.GradeSummaryDao
|
||||
import io.github.wulkanowy.data.db.dao.HomeworkDao
|
||||
import io.github.wulkanowy.data.db.dao.LuckyNumberDao
|
||||
@ -36,8 +37,9 @@ import io.github.wulkanowy.data.db.entities.CompletedLesson
|
||||
import io.github.wulkanowy.data.db.entities.Conference
|
||||
import io.github.wulkanowy.data.db.entities.Exam
|
||||
import io.github.wulkanowy.data.db.entities.Grade
|
||||
import io.github.wulkanowy.data.db.entities.GradePartialStatistics
|
||||
import io.github.wulkanowy.data.db.entities.GradePointsStatistics
|
||||
import io.github.wulkanowy.data.db.entities.GradeStatistics
|
||||
import io.github.wulkanowy.data.db.entities.GradeSemesterStatistics
|
||||
import io.github.wulkanowy.data.db.entities.GradeSummary
|
||||
import io.github.wulkanowy.data.db.entities.Homework
|
||||
import io.github.wulkanowy.data.db.entities.LuckyNumber
|
||||
@ -73,6 +75,7 @@ import io.github.wulkanowy.data.db.migrations.Migration25
|
||||
import io.github.wulkanowy.data.db.migrations.Migration26
|
||||
import io.github.wulkanowy.data.db.migrations.Migration27
|
||||
import io.github.wulkanowy.data.db.migrations.Migration28
|
||||
import io.github.wulkanowy.data.db.migrations.Migration29
|
||||
import io.github.wulkanowy.data.db.migrations.Migration3
|
||||
import io.github.wulkanowy.data.db.migrations.Migration4
|
||||
import io.github.wulkanowy.data.db.migrations.Migration5
|
||||
@ -93,8 +96,9 @@ import javax.inject.Singleton
|
||||
AttendanceSummary::class,
|
||||
Grade::class,
|
||||
GradeSummary::class,
|
||||
GradeStatistics::class,
|
||||
GradePartialStatistics::class,
|
||||
GradePointsStatistics::class,
|
||||
GradeSemesterStatistics::class,
|
||||
Message::class,
|
||||
MessageAttachment::class,
|
||||
Note::class,
|
||||
@ -116,7 +120,7 @@ import javax.inject.Singleton
|
||||
abstract class AppDatabase : RoomDatabase() {
|
||||
|
||||
companion object {
|
||||
const val VERSION_SCHEMA = 28
|
||||
const val VERSION_SCHEMA = 29
|
||||
|
||||
fun getMigrations(sharedPrefProvider: SharedPrefProvider): Array<Migration> {
|
||||
return arrayOf(
|
||||
@ -147,6 +151,7 @@ abstract class AppDatabase : RoomDatabase() {
|
||||
Migration26(),
|
||||
Migration27(),
|
||||
Migration28(),
|
||||
Migration29()
|
||||
)
|
||||
}
|
||||
|
||||
@ -176,9 +181,11 @@ abstract class AppDatabase : RoomDatabase() {
|
||||
|
||||
abstract val gradeSummaryDao: GradeSummaryDao
|
||||
|
||||
abstract val gradeStatistics: GradeStatisticsDao
|
||||
abstract val gradePartialStatisticsDao: GradePartialStatisticsDao
|
||||
|
||||
abstract val gradePointsStatistics: GradePointsStatisticsDao
|
||||
abstract val gradePointsStatisticsDao: GradePointsStatisticsDao
|
||||
|
||||
abstract val gradeSemesterStatisticsDao: GradeSemesterStatisticsDao
|
||||
|
||||
abstract val messagesDao: MessagesDao
|
||||
|
||||
|
@ -0,0 +1,13 @@
|
||||
package io.github.wulkanowy.data.db.dao
|
||||
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Query
|
||||
import io.github.wulkanowy.data.db.entities.GradePartialStatistics
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
@Dao
|
||||
interface GradePartialStatisticsDao : BaseDao<GradePartialStatistics> {
|
||||
|
||||
@Query("SELECT * FROM GradePartialStatistics WHERE student_id = :studentId AND semester_id = :semesterId")
|
||||
fun loadAll(semesterId: Int, studentId: Int): Flow<List<GradePartialStatistics>>
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
package io.github.wulkanowy.data.db.dao
|
||||
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Query
|
||||
import io.github.wulkanowy.data.db.entities.GradeSemesterStatistics
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
@Dao
|
||||
interface GradeSemesterStatisticsDao : BaseDao<GradeSemesterStatistics> {
|
||||
|
||||
@Query("SELECT * FROM GradeSemesterStatistics WHERE student_id = :studentId AND semester_id = :semesterId")
|
||||
fun loadAll(semesterId: Int, studentId: Int): Flow<List<GradeSemesterStatistics>>
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
package io.github.wulkanowy.data.db.dao
|
||||
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Query
|
||||
import io.github.wulkanowy.data.db.entities.GradeStatistics
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Singleton
|
||||
@Dao
|
||||
interface GradeStatisticsDao : BaseDao<GradeStatistics> {
|
||||
|
||||
@Query("SELECT * FROM GradesStatistics WHERE student_id = :studentId AND semester_id = :semesterId AND subject = :subjectName AND is_semester = :isSemester")
|
||||
fun loadSubject(semesterId: Int, studentId: Int, subjectName: String, isSemester: Boolean): Flow<List<GradeStatistics>>
|
||||
|
||||
@Query("SELECT * FROM GradesStatistics WHERE student_id = :studentId AND semester_id = :semesterId AND is_semester = :isSemester")
|
||||
fun loadAll(semesterId: Int, studentId: Int, isSemester: Boolean): Flow<List<GradeStatistics>>
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
package io.github.wulkanowy.data.db.entities
|
||||
|
||||
import androidx.room.ColumnInfo
|
||||
import androidx.room.Entity
|
||||
import androidx.room.PrimaryKey
|
||||
|
||||
@Entity(tableName = "GradePartialStatistics")
|
||||
data class GradePartialStatistics(
|
||||
|
||||
@ColumnInfo(name = "student_id")
|
||||
val studentId: Int,
|
||||
|
||||
@ColumnInfo(name = "semester_id")
|
||||
val semesterId: Int,
|
||||
|
||||
val subject: String,
|
||||
|
||||
@ColumnInfo(name = "class_average")
|
||||
val classAverage: String,
|
||||
|
||||
@ColumnInfo(name = "student_average")
|
||||
val studentAverage: String,
|
||||
|
||||
@ColumnInfo(name = "class_amounts")
|
||||
val classAmounts: List<Int>,
|
||||
|
||||
@ColumnInfo(name = "student_amounts")
|
||||
val studentAmounts: List<Int>
|
||||
|
||||
) {
|
||||
@PrimaryKey(autoGenerate = true)
|
||||
var id: Long = 0
|
||||
}
|
@ -4,8 +4,8 @@ import androidx.room.ColumnInfo
|
||||
import androidx.room.Entity
|
||||
import androidx.room.PrimaryKey
|
||||
|
||||
@Entity(tableName = "GradesStatistics")
|
||||
data class GradeStatistics(
|
||||
@Entity(tableName = "GradeSemesterStatistics")
|
||||
data class GradeSemesterStatistics(
|
||||
|
||||
@ColumnInfo(name = "student_id")
|
||||
val studentId: Int,
|
||||
@ -15,13 +15,14 @@ data class GradeStatistics(
|
||||
|
||||
val subject: String,
|
||||
|
||||
val grade: Int,
|
||||
val amounts: List<Int>,
|
||||
|
||||
val amount: Int,
|
||||
|
||||
@ColumnInfo(name = "is_semester")
|
||||
val semester: Boolean
|
||||
@ColumnInfo(name = "student_grade")
|
||||
val studentGrade: Int
|
||||
) {
|
||||
@PrimaryKey(autoGenerate = true)
|
||||
var id: Long = 0
|
||||
|
||||
@Transient
|
||||
var average: String = ""
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
package io.github.wulkanowy.data.db.migrations
|
||||
|
||||
import androidx.room.migration.Migration
|
||||
import androidx.sqlite.db.SupportSQLiteDatabase
|
||||
|
||||
class Migration29 : Migration(28, 29) {
|
||||
|
||||
override fun migrate(database: SupportSQLiteDatabase) {
|
||||
database.execSQL("DROP TABLE IF EXISTS GradesStatistics")
|
||||
database.execSQL("""
|
||||
CREATE TABLE IF NOT EXISTS GradeSemesterStatistics (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
|
||||
student_id INTEGER NOT NULL,
|
||||
semester_id INTEGER NOT NULL,
|
||||
subject TEXT NOT NULL,
|
||||
amounts TEXT NOT NULL,
|
||||
student_grade INTEGER NOT NULL
|
||||
)
|
||||
""")
|
||||
database.execSQL("""
|
||||
CREATE TABLE IF NOT EXISTS GradePartialStatistics (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
|
||||
student_id INTEGER NOT NULL,
|
||||
semester_id INTEGER NOT NULL,
|
||||
subject TEXT NOT NULL,
|
||||
class_average TEXT NOT NULL,
|
||||
student_average TEXT NOT NULL,
|
||||
class_amounts TEXT NOT NULL,
|
||||
student_amounts TEXT NOT NULL
|
||||
)
|
||||
""")
|
||||
}
|
||||
}
|
@ -1,14 +1,19 @@
|
||||
package io.github.wulkanowy.data.pojos
|
||||
|
||||
import io.github.wulkanowy.data.db.entities.GradePartialStatistics
|
||||
import io.github.wulkanowy.data.db.entities.GradePointsStatistics
|
||||
import io.github.wulkanowy.data.db.entities.GradeStatistics
|
||||
import io.github.wulkanowy.data.db.entities.GradeSemesterStatistics
|
||||
import io.github.wulkanowy.ui.modules.grade.statistics.ViewType
|
||||
|
||||
data class GradeStatisticsItem(
|
||||
|
||||
val type: ViewType,
|
||||
|
||||
val partial: List<GradeStatistics>,
|
||||
val average: String,
|
||||
|
||||
val partial: GradePartialStatistics?,
|
||||
|
||||
val semester: GradeSemesterStatistics?,
|
||||
|
||||
val points: GradePointsStatistics?
|
||||
)
|
||||
|
@ -1,9 +1,11 @@
|
||||
package io.github.wulkanowy.data.repositories.gradestatistics
|
||||
|
||||
import io.github.wulkanowy.data.db.dao.GradePartialStatisticsDao
|
||||
import io.github.wulkanowy.data.db.dao.GradePointsStatisticsDao
|
||||
import io.github.wulkanowy.data.db.dao.GradeStatisticsDao
|
||||
import io.github.wulkanowy.data.db.dao.GradeSemesterStatisticsDao
|
||||
import io.github.wulkanowy.data.db.entities.GradePartialStatistics
|
||||
import io.github.wulkanowy.data.db.entities.GradePointsStatistics
|
||||
import io.github.wulkanowy.data.db.entities.GradeStatistics
|
||||
import io.github.wulkanowy.data.db.entities.GradeSemesterStatistics
|
||||
import io.github.wulkanowy.data.db.entities.Semester
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import javax.inject.Inject
|
||||
@ -11,31 +13,47 @@ import javax.inject.Singleton
|
||||
|
||||
@Singleton
|
||||
class GradeStatisticsLocal @Inject constructor(
|
||||
private val gradeStatisticsDb: GradeStatisticsDao,
|
||||
private val gradePointsStatisticsDb: GradePointsStatisticsDao
|
||||
private val gradePartialStatisticsDb: GradePartialStatisticsDao,
|
||||
private val gradePointsStatisticsDb: GradePointsStatisticsDao,
|
||||
private val gradeSemesterStatisticsDb: GradeSemesterStatisticsDao
|
||||
) {
|
||||
|
||||
fun getGradesStatistics(semester: Semester, isSemester: Boolean): Flow<List<GradeStatistics>> {
|
||||
return gradeStatisticsDb.loadAll(semester.semesterId, semester.studentId, isSemester)
|
||||
// partial
|
||||
fun getGradePartialStatistics(semester: Semester): Flow<List<GradePartialStatistics>> {
|
||||
return gradePartialStatisticsDb.loadAll(semester.semesterId, semester.studentId)
|
||||
}
|
||||
|
||||
fun getGradesPointsStatistics(semester: Semester): Flow<List<GradePointsStatistics>> {
|
||||
suspend fun saveGradePartialStatistics(items: List<GradePartialStatistics>) {
|
||||
gradePartialStatisticsDb.insertAll(items)
|
||||
}
|
||||
|
||||
suspend fun deleteGradePartialStatistics(items: List<GradePartialStatistics>) {
|
||||
gradePartialStatisticsDb.deleteAll(items)
|
||||
}
|
||||
|
||||
// points
|
||||
fun getGradePointsStatistics(semester: Semester): Flow<List<GradePointsStatistics>> {
|
||||
return gradePointsStatisticsDb.loadAll(semester.semesterId, semester.studentId)
|
||||
}
|
||||
|
||||
suspend fun saveGradesStatistics(gradesStatistics: List<GradeStatistics>) {
|
||||
gradeStatisticsDb.insertAll(gradesStatistics)
|
||||
}
|
||||
|
||||
suspend fun saveGradesPointsStatistics(gradePointsStatistics: List<GradePointsStatistics>) {
|
||||
suspend fun saveGradePointsStatistics(gradePointsStatistics: List<GradePointsStatistics>) {
|
||||
gradePointsStatisticsDb.insertAll(gradePointsStatistics)
|
||||
}
|
||||
|
||||
suspend fun deleteGradesStatistics(gradesStatistics: List<GradeStatistics>) {
|
||||
gradeStatisticsDb.deleteAll(gradesStatistics)
|
||||
}
|
||||
|
||||
suspend fun deleteGradesPointsStatistics(gradesPointsStatistics: List<GradePointsStatistics>) {
|
||||
suspend fun deleteGradePointsStatistics(gradesPointsStatistics: List<GradePointsStatistics>) {
|
||||
gradePointsStatisticsDb.deleteAll(gradesPointsStatistics)
|
||||
}
|
||||
|
||||
// semester
|
||||
fun getGradeSemesterStatistics(semester: Semester): Flow<List<GradeSemesterStatistics>> {
|
||||
return gradeSemesterStatisticsDb.loadAll(semester.semesterId, semester.studentId)
|
||||
}
|
||||
|
||||
suspend fun saveGradeSemesterStatistics(items: List<GradeSemesterStatistics>) {
|
||||
gradeSemesterStatisticsDb.insertAll(items)
|
||||
}
|
||||
|
||||
suspend fun deleteGradeSemesterStatistics(items: List<GradeSemesterStatistics>) {
|
||||
gradeSemesterStatisticsDb.deleteAll(items)
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,8 @@
|
||||
package io.github.wulkanowy.data.repositories.gradestatistics
|
||||
|
||||
import io.github.wulkanowy.data.db.entities.GradePartialStatistics
|
||||
import io.github.wulkanowy.data.db.entities.GradePointsStatistics
|
||||
import io.github.wulkanowy.data.db.entities.GradeStatistics
|
||||
import io.github.wulkanowy.data.db.entities.GradeSemesterStatistics
|
||||
import io.github.wulkanowy.data.db.entities.Semester
|
||||
import io.github.wulkanowy.data.db.entities.Student
|
||||
import io.github.wulkanowy.sdk.Sdk
|
||||
@ -12,20 +13,38 @@ import javax.inject.Singleton
|
||||
@Singleton
|
||||
class GradeStatisticsRemote @Inject constructor(private val sdk: Sdk) {
|
||||
|
||||
suspend fun getGradeStatistics(student: Student, semester: Semester, isSemester: Boolean): List<GradeStatistics> {
|
||||
return sdk.init(student).switchDiary(semester.diaryId, semester.schoolYear).let {
|
||||
if (isSemester) it.getGradesAnnualStatistics(semester.semesterId)
|
||||
else it.getGradesPartialStatistics(semester.semesterId)
|
||||
}.map {
|
||||
GradeStatistics(
|
||||
semesterId = semester.semesterId,
|
||||
studentId = semester.studentId,
|
||||
subject = it.subject,
|
||||
grade = it.gradeValue,
|
||||
amount = it.amount,
|
||||
semester = isSemester
|
||||
)
|
||||
}
|
||||
suspend fun getGradePartialStatistics(student: Student, semester: Semester): List<GradePartialStatistics> {
|
||||
return sdk.init(student).switchDiary(semester.diaryId, semester.schoolYear)
|
||||
.getGradesPartialStatistics(semester.semesterId)
|
||||
.map {
|
||||
GradePartialStatistics(
|
||||
semesterId = semester.semesterId,
|
||||
studentId = student.studentId,
|
||||
subject = it.subject,
|
||||
classAverage = it.classAverage,
|
||||
studentAverage = it.studentAverage,
|
||||
classAmounts = it.classItems
|
||||
.sortedBy { item -> item.grade }
|
||||
.map { item -> item.amount },
|
||||
studentAmounts = it.studentItems.map { item -> item.amount }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun getGradeSemesterStatistics(student: Student, semester: Semester): List<GradeSemesterStatistics> {
|
||||
return sdk.init(student).switchDiary(semester.diaryId, semester.schoolYear)
|
||||
.getGradesSemesterStatistics(semester.semesterId)
|
||||
.map {
|
||||
GradeSemesterStatistics(
|
||||
semesterId = semester.semesterId,
|
||||
studentId = semester.studentId,
|
||||
subject = it.subject,
|
||||
amounts = it.items
|
||||
.sortedBy { item -> item.grade }
|
||||
.map { item -> item.amount },
|
||||
studentGrade = it.items.singleOrNull { item -> item.isStudentHere }?.grade ?: 0
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun getGradePointsStatistics(student: Student, semester: Semester): List<GradePointsStatistics> {
|
||||
|
@ -1,13 +1,15 @@
|
||||
package io.github.wulkanowy.data.repositories.gradestatistics
|
||||
|
||||
import io.github.wulkanowy.data.db.entities.GradePartialStatistics
|
||||
import io.github.wulkanowy.data.db.entities.GradePointsStatistics
|
||||
import io.github.wulkanowy.data.db.entities.GradeStatistics
|
||||
import io.github.wulkanowy.data.db.entities.GradeSemesterStatistics
|
||||
import io.github.wulkanowy.data.db.entities.Semester
|
||||
import io.github.wulkanowy.data.db.entities.Student
|
||||
import io.github.wulkanowy.data.pojos.GradeStatisticsItem
|
||||
import io.github.wulkanowy.ui.modules.grade.statistics.ViewType
|
||||
import io.github.wulkanowy.utils.networkBoundResource
|
||||
import io.github.wulkanowy.utils.uniqueSubtract
|
||||
import java.util.Locale
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
@ -17,55 +19,125 @@ class GradeStatisticsRepository @Inject constructor(
|
||||
private val remote: GradeStatisticsRemote
|
||||
) {
|
||||
|
||||
fun getGradesStatistics(student: Student, semester: Semester, subjectName: String, isSemester: Boolean, forceRefresh: Boolean) = networkBoundResource(
|
||||
fun getGradesPartialStatistics(student: Student, semester: Semester, subjectName: String, forceRefresh: Boolean) = networkBoundResource(
|
||||
shouldFetch = { it.isEmpty() || forceRefresh },
|
||||
query = { local.getGradesStatistics(semester, isSemester) },
|
||||
fetch = { remote.getGradeStatistics(student, semester, isSemester) },
|
||||
query = { local.getGradePartialStatistics(semester) },
|
||||
fetch = { remote.getGradePartialStatistics(student, semester) },
|
||||
saveFetchResult = { old, new ->
|
||||
local.deleteGradesStatistics(old uniqueSubtract new)
|
||||
local.saveGradesStatistics(new uniqueSubtract old)
|
||||
local.deleteGradePartialStatistics(old uniqueSubtract new)
|
||||
local.saveGradePartialStatistics(new uniqueSubtract old)
|
||||
},
|
||||
mapResult = { items ->
|
||||
when (subjectName) {
|
||||
"Wszystkie" -> items.groupBy { it.grade }.map {
|
||||
GradeStatistics(semester.studentId, semester.semesterId, subjectName, it.key,
|
||||
it.value.fold(0) { acc, e -> acc + e.amount }, false)
|
||||
} + items
|
||||
"Wszystkie" -> {
|
||||
val numerator = items.map {
|
||||
it.classAverage.replace(",", ".").toDoubleOrNull() ?: .0
|
||||
}.filterNot { it == .0 }
|
||||
(items.reversed() + GradePartialStatistics(
|
||||
studentId = semester.studentId,
|
||||
semesterId = semester.semesterId,
|
||||
subject = subjectName,
|
||||
classAverage = if (numerator.isEmpty()) "" else numerator.average().let {
|
||||
"%.2f".format(Locale.FRANCE, it)
|
||||
},
|
||||
studentAverage = "",
|
||||
classAmounts = items.map { it.classAmounts }.sumGradeAmounts(),
|
||||
studentAmounts = items.map { it.studentAmounts }.sumGradeAmounts()
|
||||
)).reversed()
|
||||
}
|
||||
else -> items.filter { it.subject == subjectName }
|
||||
}.mapToStatisticItems()
|
||||
}.mapPartialToStatisticItems()
|
||||
}
|
||||
)
|
||||
|
||||
fun getGradesSemesterStatistics(student: Student, semester: Semester, subjectName: String, forceRefresh: Boolean) = networkBoundResource(
|
||||
shouldFetch = { it.isEmpty() || forceRefresh },
|
||||
query = { local.getGradeSemesterStatistics(semester) },
|
||||
fetch = { remote.getGradeSemesterStatistics(student, semester) },
|
||||
saveFetchResult = { old, new ->
|
||||
local.deleteGradeSemesterStatistics(old uniqueSubtract new)
|
||||
local.saveGradeSemesterStatistics(new uniqueSubtract old)
|
||||
},
|
||||
mapResult = { items ->
|
||||
val itemsWithAverage = items.map { item ->
|
||||
item.copy().apply {
|
||||
val denominator = item.amounts.sum()
|
||||
average = if (denominator == 0) "" else (item.amounts.mapIndexed { gradeValue, amount ->
|
||||
(gradeValue + 1) * amount
|
||||
}.sum().toDouble() / denominator).let {
|
||||
"%.2f".format(Locale.FRANCE, it)
|
||||
}
|
||||
}
|
||||
}
|
||||
when (subjectName) {
|
||||
"Wszystkie" -> (itemsWithAverage.reversed() + GradeSemesterStatistics(
|
||||
studentId = semester.studentId,
|
||||
semesterId = semester.semesterId,
|
||||
subject = subjectName,
|
||||
amounts = itemsWithAverage.map { it.amounts }.sumGradeAmounts(),
|
||||
studentGrade = 0
|
||||
).apply {
|
||||
average = itemsWithAverage.mapNotNull { it.average.replace(",", ".").toDoubleOrNull() }.average().let {
|
||||
"%.2f".format(Locale.FRANCE, it)
|
||||
}
|
||||
}).reversed()
|
||||
else -> itemsWithAverage.filter { it.subject == subjectName }
|
||||
}.mapSemesterToStatisticItems()
|
||||
}
|
||||
)
|
||||
|
||||
fun getGradesPointsStatistics(student: Student, semester: Semester, subjectName: String, forceRefresh: Boolean) = networkBoundResource(
|
||||
shouldFetch = { it.isEmpty() || forceRefresh },
|
||||
query = { local.getGradesPointsStatistics(semester) },
|
||||
query = { local.getGradePointsStatistics(semester) },
|
||||
fetch = { remote.getGradePointsStatistics(student, semester) },
|
||||
saveFetchResult = { old, new ->
|
||||
local.deleteGradesPointsStatistics(old uniqueSubtract new)
|
||||
local.saveGradesPointsStatistics(new uniqueSubtract old)
|
||||
local.deleteGradePointsStatistics(old uniqueSubtract new)
|
||||
local.saveGradePointsStatistics(new uniqueSubtract old)
|
||||
},
|
||||
mapResult = { items ->
|
||||
when (subjectName) {
|
||||
"Wszystkie" -> items
|
||||
else -> items.filter { it.subject == subjectName }
|
||||
}.mapToStatisticsItem()
|
||||
}.mapPointsToStatisticsItems()
|
||||
}
|
||||
)
|
||||
|
||||
private fun List<GradeStatistics>.mapToStatisticItems() = groupBy { it.subject }.map {
|
||||
private fun List<List<Int>>.sumGradeAmounts(): List<Int> {
|
||||
val result = mutableListOf(0, 0, 0, 0, 0, 0)
|
||||
forEach {
|
||||
it.forEachIndexed { grade, amount ->
|
||||
result[grade] += amount
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
private fun List<GradePartialStatistics>.mapPartialToStatisticItems() = filterNot { it.classAmounts.isEmpty() }.map {
|
||||
GradeStatisticsItem(
|
||||
type = ViewType.PARTIAL,
|
||||
partial = it.value
|
||||
.sortedByDescending { item -> item.grade }
|
||||
.filter { item -> item.amount != 0 },
|
||||
points = null
|
||||
average = it.classAverage,
|
||||
partial = it,
|
||||
points = null,
|
||||
semester = null
|
||||
)
|
||||
}
|
||||
|
||||
private fun List<GradePointsStatistics>.mapToStatisticsItem() = map {
|
||||
private fun List<GradeSemesterStatistics>.mapSemesterToStatisticItems() = filterNot { it.amounts.isEmpty() }.map {
|
||||
GradeStatisticsItem(
|
||||
type = ViewType.SEMESTER,
|
||||
partial = null,
|
||||
points = null,
|
||||
average = "",
|
||||
semester = it
|
||||
)
|
||||
}
|
||||
|
||||
private fun List<GradePointsStatistics>.mapPointsToStatisticsItems() = map {
|
||||
GradeStatisticsItem(
|
||||
type = ViewType.POINTS,
|
||||
partial = emptyList(),
|
||||
partial = null,
|
||||
semester = null,
|
||||
average = "",
|
||||
points = it
|
||||
)
|
||||
}
|
||||
|
@ -12,8 +12,8 @@ class GradeStatisticsWork @Inject constructor(
|
||||
|
||||
override suspend fun doWork(student: Student, semester: Semester) {
|
||||
with(gradeStatisticsRepository) {
|
||||
getGradesStatistics(student, semester, "Wszystkie", isSemester = true, forceRefresh = true).waitForResult()
|
||||
getGradesStatistics(student, semester, "Wszystkie", isSemester = false, forceRefresh = true).waitForResult()
|
||||
getGradesPartialStatistics(student, semester, "Wszystkie", forceRefresh = true).waitForResult()
|
||||
getGradesSemesterStatistics(student, semester, "Wszystkie", forceRefresh = true).waitForResult()
|
||||
getGradesPointsStatistics(student, semester, "Wszystkie", forceRefresh = true).waitForResult()
|
||||
}
|
||||
}
|
||||
|
@ -17,8 +17,9 @@ import com.github.mikephil.charting.data.PieDataSet
|
||||
import com.github.mikephil.charting.data.PieEntry
|
||||
import com.github.mikephil.charting.formatter.ValueFormatter
|
||||
import io.github.wulkanowy.R
|
||||
import io.github.wulkanowy.data.db.entities.GradePartialStatistics
|
||||
import io.github.wulkanowy.data.db.entities.GradePointsStatistics
|
||||
import io.github.wulkanowy.data.db.entities.GradeStatistics
|
||||
import io.github.wulkanowy.data.db.entities.GradeSemesterStatistics
|
||||
import io.github.wulkanowy.data.pojos.GradeStatisticsItem
|
||||
import io.github.wulkanowy.databinding.ItemGradeStatisticsBarBinding
|
||||
import io.github.wulkanowy.databinding.ItemGradeStatisticsPieBinding
|
||||
@ -68,22 +69,32 @@ class GradeStatisticsAdapter @Inject constructor() :
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
|
||||
val inflater = LayoutInflater.from(parent.context)
|
||||
return when (viewType) {
|
||||
ViewType.PARTIAL.id, ViewType.SEMESTER.id -> PieViewHolder(ItemGradeStatisticsPieBinding.inflate(inflater, parent, false))
|
||||
ViewType.POINTS.id -> BarViewHolder(ItemGradeStatisticsBarBinding.inflate(inflater, parent, false))
|
||||
ViewType.PARTIAL.id -> PartialViewHolder(ItemGradeStatisticsPieBinding.inflate(inflater, parent, false))
|
||||
ViewType.SEMESTER.id -> SemesterViewHolder(ItemGradeStatisticsPieBinding.inflate(inflater, parent, false))
|
||||
ViewType.POINTS.id -> PointsViewHolder(ItemGradeStatisticsBarBinding.inflate(inflater, parent, false))
|
||||
else -> throw IllegalStateException()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
|
||||
when (holder) {
|
||||
is PieViewHolder -> bindPieChart(holder, items[position].partial)
|
||||
is BarViewHolder -> bindBarChart(holder, items[position].points!!)
|
||||
is PartialViewHolder -> bindPartialChart(holder, items[position].partial!!)
|
||||
is SemesterViewHolder -> bindSemesterChart(holder, items[position].semester!!)
|
||||
is PointsViewHolder -> bindBarChart(holder, items[position].points!!)
|
||||
}
|
||||
}
|
||||
|
||||
private fun bindPieChart(holder: PieViewHolder, partials: List<GradeStatistics>) {
|
||||
with(holder.binding.gradeStatisticsPieTitle) {
|
||||
text = partials.firstOrNull()?.subject
|
||||
private fun bindPartialChart(holder: PartialViewHolder, partials: GradePartialStatistics) {
|
||||
bindPieChart(holder.binding, partials.subject, partials.classAverage, partials.classAmounts)
|
||||
}
|
||||
|
||||
private fun bindSemesterChart(holder: SemesterViewHolder, semester: GradeSemesterStatistics) {
|
||||
bindPieChart(holder.binding, semester.subject, semester.average, semester.amounts)
|
||||
}
|
||||
|
||||
private fun bindPieChart(binding: ItemGradeStatisticsPieBinding, subject: String, average: String, amounts: List<Int>) {
|
||||
with(binding.gradeStatisticsPieTitle) {
|
||||
text = subject
|
||||
visibility = if (items.size == 1 || !showAllSubjectsOnList) GONE else VISIBLE
|
||||
}
|
||||
|
||||
@ -92,22 +103,23 @@ class GradeStatisticsAdapter @Inject constructor() :
|
||||
else -> materialGradeColors
|
||||
}
|
||||
|
||||
val dataset = PieDataSet(partials.map {
|
||||
PieEntry(it.amount.toFloat(), it.grade.toString())
|
||||
}, "Legenda")
|
||||
val dataset = PieDataSet(amounts.mapIndexed { grade, amount ->
|
||||
PieEntry(amount.toFloat(), (grade + 1).toString())
|
||||
}.reversed().filterNot { it.value == 0f }, "Legenda")
|
||||
|
||||
with(dataset) {
|
||||
valueTextSize = 12f
|
||||
sliceSpace = 1f
|
||||
valueTextColor = Color.WHITE
|
||||
setColors(partials.map {
|
||||
gradeColors.single { color -> color.first == it.grade }.second
|
||||
}.toIntArray(), holder.binding.root.context)
|
||||
val grades = amounts.mapIndexed { grade, amount -> (grade + 1) to amount }.filterNot { it.second == 0 }
|
||||
setColors(grades.reversed().map { (grade, _) ->
|
||||
gradeColors.single { color -> color.first == grade }.second
|
||||
}.toIntArray(), binding.root.context)
|
||||
}
|
||||
|
||||
with(holder.binding.gradeStatisticsPie) {
|
||||
with(binding.gradeStatisticsPie) {
|
||||
setTouchEnabled(false)
|
||||
if (partials.size == 1) animateXY(1000, 1000)
|
||||
if (amounts.size == 1) animateXY(1000, 1000)
|
||||
data = PieData(dataset).apply {
|
||||
setValueFormatter(object : ValueFormatter() {
|
||||
override fun getPieLabel(value: Float, pieEntry: PieEntry): String {
|
||||
@ -128,8 +140,9 @@ class GradeStatisticsAdapter @Inject constructor() :
|
||||
|
||||
minAngleForSlices = 25f
|
||||
description.isEnabled = false
|
||||
centerText = partials.fold(0) { acc, it -> acc + it.amount }
|
||||
.let { resources.getQuantityString(R.plurals.grade_number_item, it, it) }
|
||||
centerText = amounts.fold(0) { acc, it -> acc + it }
|
||||
.let { resources.getQuantityString(R.plurals.grade_number_item, it, it) } +
|
||||
("\n\nŚrednia: $average").takeIf { average.isNotBlank() }.orEmpty()
|
||||
|
||||
setHoleColor(context.getThemeAttrColor(android.R.attr.windowBackground))
|
||||
setCenterTextColor(context.getThemeAttrColor(android.R.attr.textColorPrimary))
|
||||
@ -137,7 +150,7 @@ class GradeStatisticsAdapter @Inject constructor() :
|
||||
}
|
||||
}
|
||||
|
||||
private fun bindBarChart(holder: BarViewHolder, points: GradePointsStatistics) {
|
||||
private fun bindBarChart(holder: PointsViewHolder, points: GradePointsStatistics) {
|
||||
with(holder.binding.gradeStatisticsBarTitle) {
|
||||
text = points.subject
|
||||
visibility = if (items.size == 1) GONE else VISIBLE
|
||||
@ -200,9 +213,12 @@ class GradeStatisticsAdapter @Inject constructor() :
|
||||
}
|
||||
}
|
||||
|
||||
private class PieViewHolder(val binding: ItemGradeStatisticsPieBinding) :
|
||||
private class PartialViewHolder(val binding: ItemGradeStatisticsPieBinding) :
|
||||
RecyclerView.ViewHolder(binding.root)
|
||||
|
||||
private class BarViewHolder(val binding: ItemGradeStatisticsBarBinding) :
|
||||
private class SemesterViewHolder(val binding: ItemGradeStatisticsPieBinding) :
|
||||
RecyclerView.ViewHolder(binding.root)
|
||||
|
||||
private class PointsViewHolder(val binding: ItemGradeStatisticsBarBinding) :
|
||||
RecyclerView.ViewHolder(binding.root)
|
||||
}
|
||||
|
@ -153,8 +153,8 @@ class GradeStatisticsPresenter @Inject constructor(
|
||||
|
||||
with(gradeStatisticsRepository) {
|
||||
when (type) {
|
||||
ViewType.SEMESTER -> getGradesStatistics(student, semester, currentSubjectName, true, forceRefresh)
|
||||
ViewType.PARTIAL -> getGradesStatistics(student, semester, currentSubjectName, false, forceRefresh)
|
||||
ViewType.PARTIAL -> getGradesPartialStatistics(student, semester, currentSubjectName, forceRefresh)
|
||||
ViewType.SEMESTER -> getGradesSemesterStatistics(student, semester, currentSubjectName, forceRefresh)
|
||||
ViewType.POINTS -> getGradesPointsStatistics(student, semester, currentSubjectName, forceRefresh)
|
||||
}
|
||||
}
|
||||
@ -164,8 +164,15 @@ class GradeStatisticsPresenter @Inject constructor(
|
||||
Status.SUCCESS -> {
|
||||
Timber.i("Loading grade stats result: Success")
|
||||
view?.run {
|
||||
showEmpty(it.data!!.isEmpty() || it.data.first().partial.isEmpty())
|
||||
showContent(it.data.isNotEmpty() && it.data.first().partial.isNotEmpty())
|
||||
val isNoContent = it.data!!.isEmpty() || when (type) {
|
||||
ViewType.SEMESTER -> it.data.firstOrNull()?.semester?.amounts.orEmpty().sum() == 0
|
||||
ViewType.PARTIAL -> it.data.firstOrNull()?.partial?.classAmounts.orEmpty().sum() == 0
|
||||
ViewType.POINTS -> it.data.firstOrNull()?.points?.let { points ->
|
||||
points.student == .0 && points.others == .0
|
||||
} ?: false
|
||||
}
|
||||
showEmpty(isNoContent)
|
||||
showContent(!isNoContent)
|
||||
showErrorView(false)
|
||||
updateData(it.data, preferencesRepository.gradeColorTheme, preferencesRepository.showAllSubjectsOnStatisticsList)
|
||||
showSubjects(!preferencesRepository.showAllSubjectsOnStatisticsList)
|
||||
|
@ -4,7 +4,8 @@ import io.github.wulkanowy.data.db.entities.Semester
|
||||
import io.github.wulkanowy.getStudentEntity
|
||||
import io.github.wulkanowy.sdk.Sdk
|
||||
import io.github.wulkanowy.sdk.pojo.GradePointsStatistics
|
||||
import io.github.wulkanowy.sdk.pojo.GradeStatistics
|
||||
import io.github.wulkanowy.sdk.pojo.GradeStatisticsItem
|
||||
import io.github.wulkanowy.sdk.pojo.GradeStatisticsSubject
|
||||
import io.github.wulkanowy.utils.init
|
||||
import io.mockk.MockKAnnotations
|
||||
import io.mockk.coEvery
|
||||
@ -35,8 +36,8 @@ class GradeStatisticsRemoteTest {
|
||||
@Test
|
||||
fun getGradeStatisticsTest() {
|
||||
coEvery { mockSdk.getGradesPartialStatistics(1) } returns listOf(
|
||||
getGradeStatistics("Fizyka"),
|
||||
getGradeStatistics("Matematyka")
|
||||
getGradeStatisticsPartialSubject("Fizyka"),
|
||||
getGradeStatisticsPartialSubject("Matematyka")
|
||||
)
|
||||
|
||||
every { semesterMock.studentId } returns 1
|
||||
@ -45,7 +46,7 @@ class GradeStatisticsRemoteTest {
|
||||
every { semesterMock.semesterId } returns 1
|
||||
every { mockSdk.switchDiary(any(), any()) } returns mockSdk
|
||||
|
||||
val stats = runBlocking { GradeStatisticsRemote(mockSdk).getGradeStatistics(student, semesterMock, false) }
|
||||
val stats = runBlocking { GradeStatisticsRemote(mockSdk).getGradePartialStatistics(student, semesterMock) }
|
||||
assertEquals(2, stats.size)
|
||||
}
|
||||
|
||||
@ -66,19 +67,24 @@ class GradeStatisticsRemoteTest {
|
||||
assertEquals(2, stats.size)
|
||||
}
|
||||
|
||||
private fun getGradeStatistics(subjectName: String): GradeStatistics {
|
||||
return GradeStatistics(
|
||||
private fun getGradeStatisticsPartialSubject(subjectName: String): GradeStatisticsSubject {
|
||||
return GradeStatisticsSubject(
|
||||
subject = subjectName,
|
||||
gradeValue = 5,
|
||||
amount = 10,
|
||||
grade = "",
|
||||
semesterId = 1
|
||||
studentAverage = "",
|
||||
classAverage = "",
|
||||
classItems = listOf(
|
||||
GradeStatisticsItem(
|
||||
subject = subjectName,
|
||||
grade = 0,
|
||||
amount = 0
|
||||
)
|
||||
),
|
||||
studentItems = listOf()
|
||||
)
|
||||
}
|
||||
|
||||
private fun getGradePointsStatistics(subjectName: String): GradePointsStatistics {
|
||||
return GradePointsStatistics(
|
||||
semesterId = 1,
|
||||
subject = subjectName,
|
||||
student = 0.80,
|
||||
others = 0.40
|
||||
|
Loading…
Reference in New Issue
Block a user