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