mirror of
https://github.com/szkolny-eu/szkolny-android.git
synced 2025-02-08 09:04:36 +01:00
[UI/Grades] Add "no grade" entity in USOS, count ECTS points by term
This commit is contained in:
parent
88cd18b8c6
commit
29971777a7
@ -12,6 +12,7 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.usos.data.UsosApi
|
|||||||
import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
|
import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade
|
import pl.szczodrzynski.edziennik.data.db.entity.Grade
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_NORMAL
|
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_NORMAL
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_NO_GRADE
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
||||||
import pl.szczodrzynski.edziennik.data.db.enums.MetadataType
|
import pl.szczodrzynski.edziennik.data.db.enums.MetadataType
|
||||||
@ -40,13 +41,13 @@ class UsosApiExamReports(
|
|||||||
tag = TAG,
|
tag = TAG,
|
||||||
service = "examrep/user2",
|
service = "examrep/user2",
|
||||||
fields = listOf(
|
fields = listOf(
|
||||||
|
"id",
|
||||||
"type_description",
|
"type_description",
|
||||||
"course_unit" to listOf("id", "course_name"),
|
"course_unit" to listOf("id", "course_name"),
|
||||||
"sessions" to listOf(
|
"sessions" to listOf(
|
||||||
|
"number",
|
||||||
"description",
|
"description",
|
||||||
"issuer_grades" to listOf(
|
"issuer_grades" to listOf(
|
||||||
"exam_id",
|
|
||||||
"exam_session_number",
|
|
||||||
"value_symbol",
|
"value_symbol",
|
||||||
// "value_description",
|
// "value_description",
|
||||||
"passes",
|
"passes",
|
||||||
@ -93,6 +94,8 @@ class UsosApiExamReports(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun processExamReport(termId: String, courseId: String, examReport: JsonObject) {
|
private fun processExamReport(termId: String, courseId: String, examReport: JsonObject) {
|
||||||
|
val examId = examReport.getString("id")?.toIntOrNull()
|
||||||
|
?: return
|
||||||
val typeDescription = examReport.getLangString("type_description")
|
val typeDescription = examReport.getLangString("type_description")
|
||||||
val courseUnit = examReport.getJsonObject("course_unit")
|
val courseUnit = examReport.getJsonObject("course_unit")
|
||||||
?: return
|
?: return
|
||||||
@ -103,16 +106,26 @@ class UsosApiExamReports(
|
|||||||
val sessions = examReport.getJsonArray("sessions")
|
val sessions = examReport.getJsonArray("sessions")
|
||||||
?: return
|
?: return
|
||||||
|
|
||||||
|
val gradeCategory = data.gradeCategories[courseUnitId]
|
||||||
|
val classType = gradeCategory?.columns?.get(0)
|
||||||
|
|
||||||
|
val subject = data.getSubject(
|
||||||
|
id = null,
|
||||||
|
name = courseName,
|
||||||
|
shortName = courseId,
|
||||||
|
)
|
||||||
|
|
||||||
|
var hasGrade = false
|
||||||
|
|
||||||
for (sessionEl in sessions) {
|
for (sessionEl in sessions) {
|
||||||
if (!sessionEl.isJsonObject)
|
if (!sessionEl.isJsonObject)
|
||||||
continue
|
continue
|
||||||
val session = sessionEl.asJsonObject
|
val session = sessionEl.asJsonObject
|
||||||
|
|
||||||
|
val sessionNumber = session.getInt("number") ?: continue
|
||||||
val sessionDescription = session.getLangString("description")
|
val sessionDescription = session.getLangString("description")
|
||||||
val issuerGrade = session.getJsonObject("issuer_grades") ?: continue
|
val issuerGrade = session.getJsonObject("issuer_grades")
|
||||||
|
|
||||||
val examId = issuerGrade.getInt("exam_id") ?: continue
|
|
||||||
val sessionNumber = issuerGrade.getInt("exam_session_number") ?: continue
|
|
||||||
val valueSymbol = issuerGrade.getString("value_symbol") ?: continue
|
val valueSymbol = issuerGrade.getString("value_symbol") ?: continue
|
||||||
val passes = issuerGrade.getBoolean("passes")
|
val passes = issuerGrade.getBoolean("passes")
|
||||||
val countsIntoAverage = issuerGrade.getString("counts_into_average") ?: "T"
|
val countsIntoAverage = issuerGrade.getString("counts_into_average") ?: "T"
|
||||||
@ -121,8 +134,6 @@ class UsosApiExamReports(
|
|||||||
?.getLong("id") ?: -1L
|
?.getLong("id") ?: -1L
|
||||||
val comment = issuerGrade.getString("comment")
|
val comment = issuerGrade.getString("comment")
|
||||||
|
|
||||||
val gradeCategory = data.gradeCategories[courseUnitId]
|
|
||||||
val classType = gradeCategory?.columns?.get(0)
|
|
||||||
val value = valueSymbol.toFloatOrNull() ?: 0.0f
|
val value = valueSymbol.toFloatOrNull() ?: 0.0f
|
||||||
|
|
||||||
if (termId !in data.termNames) {
|
if (termId !in data.termNames) {
|
||||||
@ -142,13 +153,10 @@ class UsosApiExamReports(
|
|||||||
comment = termId,
|
comment = termId,
|
||||||
semester = 1,
|
semester = 1,
|
||||||
teacherId = modificationAuthorId,
|
teacherId = modificationAuthorId,
|
||||||
subjectId = data.getSubject(
|
subjectId = subject.id,
|
||||||
id = null,
|
|
||||||
name = courseName,
|
|
||||||
shortName = courseId,
|
|
||||||
).id,
|
|
||||||
addedDate = Date.fromIso(dateModified),
|
addedDate = Date.fromIso(dateModified),
|
||||||
)
|
)
|
||||||
|
hasGrade = true
|
||||||
|
|
||||||
if (sessionNumber > 1) {
|
if (sessionNumber > 1) {
|
||||||
val origId = examId * 10L + sessionNumber - 1
|
val origId = examId * 10L + sessionNumber - 1
|
||||||
@ -170,5 +178,35 @@ class UsosApiExamReports(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!hasGrade) {
|
||||||
|
// add an "empty" grade for the exam
|
||||||
|
val gradeObject = Grade(
|
||||||
|
profileId = profileId,
|
||||||
|
id = examId * 10L,
|
||||||
|
name = "...",
|
||||||
|
type = TYPE_NO_GRADE,
|
||||||
|
value = 0.0f,
|
||||||
|
weight = 0.0f,
|
||||||
|
color = 0xFFBABABD.toInt(),
|
||||||
|
category = typeDescription,
|
||||||
|
description = classType,
|
||||||
|
comment = termId,
|
||||||
|
semester = 1,
|
||||||
|
teacherId = -1L,
|
||||||
|
subjectId = subject.id,
|
||||||
|
addedDate = 0,
|
||||||
|
)
|
||||||
|
data.gradeList.add(gradeObject)
|
||||||
|
data.metadataList.add(
|
||||||
|
Metadata(
|
||||||
|
profileId,
|
||||||
|
MetadataType.GRADE,
|
||||||
|
gradeObject.id,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -55,6 +55,7 @@ open class Grade(
|
|||||||
const val TYPE_DESCRIPTIVE = 30
|
const val TYPE_DESCRIPTIVE = 30
|
||||||
const val TYPE_DESCRIPTIVE_TEXT = 31
|
const val TYPE_DESCRIPTIVE_TEXT = 31
|
||||||
const val TYPE_TEXT = 40
|
const val TYPE_TEXT = 40
|
||||||
|
const val TYPE_NO_GRADE = 100
|
||||||
}
|
}
|
||||||
|
|
||||||
@ColumnInfo(name = "gradeValueMax")
|
@ColumnInfo(name = "gradeValueMax")
|
||||||
|
@ -16,6 +16,7 @@ import kotlinx.coroutines.Job
|
|||||||
import pl.szczodrzynski.edziennik.App
|
import pl.szczodrzynski.edziennik.App
|
||||||
import pl.szczodrzynski.edziennik.R
|
import pl.szczodrzynski.edziennik.R
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade
|
import pl.szczodrzynski.edziennik.data.db.entity.Grade
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_NO_GRADE
|
||||||
import pl.szczodrzynski.edziennik.data.db.full.GradeFull
|
import pl.szczodrzynski.edziennik.data.db.full.GradeFull
|
||||||
import pl.szczodrzynski.edziennik.ext.onClick
|
import pl.szczodrzynski.edziennik.ext.onClick
|
||||||
import pl.szczodrzynski.edziennik.ext.startCoroutineTimer
|
import pl.szczodrzynski.edziennik.ext.startCoroutineTimer
|
||||||
@ -235,10 +236,13 @@ class GradesAdapter(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (item !is GradeFull || onGradeClick != null)
|
if (item !is GradeFull || (onGradeClick != null && item.type != TYPE_NO_GRADE)) {
|
||||||
holder.itemView.setOnClickListener(onClickListener)
|
holder.itemView.setOnClickListener(onClickListener)
|
||||||
else
|
holder.itemView.isEnabled = true
|
||||||
|
} else {
|
||||||
holder.itemView.setOnClickListener(null)
|
holder.itemView.setOnClickListener(null)
|
||||||
|
holder.itemView.isEnabled = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun notifyItemChanged(model: Any) {
|
fun notifyItemChanged(model: Any) {
|
||||||
|
@ -18,6 +18,7 @@ import com.mikepenz.iconics.typeface.library.community.material.CommunityMateria
|
|||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.*
|
||||||
import pl.szczodrzynski.edziennik.*
|
import pl.szczodrzynski.edziennik.*
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade
|
import pl.szczodrzynski.edziennik.data.db.entity.Grade
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_NO_GRADE
|
||||||
import pl.szczodrzynski.edziennik.data.db.enums.MetadataType
|
import pl.szczodrzynski.edziennik.data.db.enums.MetadataType
|
||||||
import pl.szczodrzynski.edziennik.data.db.full.GradeFull
|
import pl.szczodrzynski.edziennik.data.db.full.GradeFull
|
||||||
import pl.szczodrzynski.edziennik.databinding.GradesListFragmentBinding
|
import pl.szczodrzynski.edziennik.databinding.GradesListFragmentBinding
|
||||||
@ -305,18 +306,24 @@ class GradesListFragment : Fragment(), CoroutineScope {
|
|||||||
val semesterCount = mutableListOf<Float>()
|
val semesterCount = mutableListOf<Float>()
|
||||||
val totalSum = mutableListOf<Float>()
|
val totalSum = mutableListOf<Float>()
|
||||||
val totalCount = mutableListOf<Float>()
|
val totalCount = mutableListOf<Float>()
|
||||||
val ectsPoints = mutableMapOf<Long, Float>()
|
val ectsPoints = mutableMapOf<Pair<Long, String?>, Float>()
|
||||||
for (grade in grades) {
|
for (grade in grades) {
|
||||||
|
val pointsPair = grade.subjectId to grade.comment
|
||||||
|
if (grade.type == TYPE_NO_GRADE)
|
||||||
|
// reset points if there's an exam that isn't passed yet
|
||||||
|
ectsPoints[pointsPair] = 0.0f
|
||||||
|
|
||||||
if (grade.value == 0.0f || grade.weight == 0.0f)
|
if (grade.value == 0.0f || grade.weight == 0.0f)
|
||||||
continue
|
continue
|
||||||
totalSum.add(grade.value * grade.weight)
|
totalSum.add(grade.value * grade.weight)
|
||||||
totalCount.add(grade.weight)
|
totalCount.add(grade.weight)
|
||||||
|
|
||||||
if (grade.value < 3.0)
|
if (grade.value < 3.0)
|
||||||
// exam not passed, reset points for this subject
|
// exam not passed, reset points for this subject
|
||||||
ectsPoints[grade.subjectId] = 0.0f
|
ectsPoints[pointsPair] = 0.0f
|
||||||
else if (grade.subjectId !in ectsPoints)
|
else if (pointsPair !in ectsPoints)
|
||||||
// no points for this subject, simply assign
|
// no points for this subject, simply assign
|
||||||
ectsPoints[grade.subjectId] = grade.weight
|
ectsPoints[pointsPair] = grade.weight
|
||||||
|
|
||||||
if (filterTermId != null && grade.comment != filterTermId)
|
if (filterTermId != null && grade.comment != filterTermId)
|
||||||
continue
|
continue
|
||||||
|
@ -11,6 +11,7 @@ import androidx.core.view.isVisible
|
|||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import pl.szczodrzynski.edziennik.App
|
import pl.szczodrzynski.edziennik.App
|
||||||
import pl.szczodrzynski.edziennik.R
|
import pl.szczodrzynski.edziennik.R
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_NO_GRADE
|
||||||
import pl.szczodrzynski.edziennik.data.db.full.GradeFull
|
import pl.szczodrzynski.edziennik.data.db.full.GradeFull
|
||||||
import pl.szczodrzynski.edziennik.databinding.GradesItemGradeBinding
|
import pl.szczodrzynski.edziennik.databinding.GradesItemGradeBinding
|
||||||
import pl.szczodrzynski.edziennik.ui.grades.GradesAdapter
|
import pl.szczodrzynski.edziennik.ui.grades.GradesAdapter
|
||||||
@ -59,9 +60,12 @@ class GradeViewHolder(
|
|||||||
b.gradeWeight.isVisible = weightText != null
|
b.gradeWeight.isVisible = weightText != null
|
||||||
|
|
||||||
b.gradeTeacherName.text = grade.teacherName
|
b.gradeTeacherName.text = grade.teacherName
|
||||||
b.gradeAddedDate.text = Date.fromMillis(grade.addedDate).let {
|
if (grade.addedDate == 0L || grade.type == TYPE_NO_GRADE)
|
||||||
it.getRelativeString(app, 5) ?: it.formattedStringShort
|
b.gradeAddedDate.text = null
|
||||||
}
|
else
|
||||||
|
b.gradeAddedDate.text = Date.fromMillis(grade.addedDate).let {
|
||||||
|
it.getRelativeString(app, 5) ?: it.formattedStringShort
|
||||||
|
}
|
||||||
|
|
||||||
b.unread.isVisible = grade.showAsUnseen
|
b.unread.isVisible = grade.showAsUnseen
|
||||||
if (!grade.seen) {
|
if (!grade.seen) {
|
||||||
|
@ -25,6 +25,7 @@ import kotlinx.coroutines.Job
|
|||||||
import pl.szczodrzynski.edziennik.App
|
import pl.szczodrzynski.edziennik.App
|
||||||
import pl.szczodrzynski.edziennik.MainActivity
|
import pl.szczodrzynski.edziennik.MainActivity
|
||||||
import pl.szczodrzynski.edziennik.R
|
import pl.szczodrzynski.edziennik.R
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_NO_GRADE
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Subject
|
import pl.szczodrzynski.edziennik.data.db.entity.Subject
|
||||||
import pl.szczodrzynski.edziennik.data.db.full.GradeFull
|
import pl.szczodrzynski.edziennik.data.db.full.GradeFull
|
||||||
@ -70,7 +71,7 @@ class HomeGradesCard(
|
|||||||
app.db.gradeDao().getAllFromDate(profile.id, sevenDaysAgo).observe(fragment, Observer {
|
app.db.gradeDao().getAllFromDate(profile.id, sevenDaysAgo).observe(fragment, Observer {
|
||||||
grades.apply {
|
grades.apply {
|
||||||
clear()
|
clear()
|
||||||
addAll(it)
|
addAll(it.filter { it.type != TYPE_NO_GRADE })
|
||||||
}
|
}
|
||||||
update()
|
update()
|
||||||
})
|
})
|
||||||
|
@ -12,6 +12,7 @@ import pl.szczodrzynski.edziennik.App
|
|||||||
import pl.szczodrzynski.edziennik.R
|
import pl.szczodrzynski.edziennik.R
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade
|
import pl.szczodrzynski.edziennik.data.db.entity.Grade
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_NORMAL
|
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_NORMAL
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_NO_GRADE
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_POINT_AVG
|
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_POINT_AVG
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_POINT_SUM
|
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_POINT_SUM
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_YEAR_FINAL
|
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_YEAR_FINAL
|
||||||
@ -90,6 +91,7 @@ class GradesManager(val app: App) : CoroutineScope {
|
|||||||
else
|
else
|
||||||
context.getString(R.string.grades_weight_format, format.format(grade.weight))
|
context.getString(R.string.grades_weight_format, format.format(grade.weight))
|
||||||
TYPE_POINT_AVG -> context.getString(R.string.grades_max_points_format, format.format(grade.valueMax))
|
TYPE_POINT_AVG -> context.getString(R.string.grades_max_points_format, format.format(grade.valueMax))
|
||||||
|
TYPE_NO_GRADE -> context.getString(R.string.grades_weight_no_grade)
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -350,16 +350,14 @@
|
|||||||
android:layout_width="1dp"
|
android:layout_width="1dp"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_marginTop="8dp"
|
android:layout_marginTop="8dp"
|
||||||
android:background="@drawable/divider"
|
android:background="@drawable/divider" />
|
||||||
android:visibility="gone" />
|
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:gravity="center_horizontal"
|
android:gravity="center_horizontal"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical">
|
||||||
android:visibility="gone">
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
|
@ -500,6 +500,7 @@
|
|||||||
<string name="grades_value_format">wartość: %s</string>
|
<string name="grades_value_format">wartość: %s</string>
|
||||||
<string name="grades_weight_format">waga %s</string>
|
<string name="grades_weight_format">waga %s</string>
|
||||||
<string name="grades_weight_not_counted">nie liczona do śr.</string>
|
<string name="grades_weight_not_counted">nie liczona do śr.</string>
|
||||||
|
<string name="grades_weight_no_grade">brak oceny</string>
|
||||||
<string name="grades_year_average_format">koniec roku: %s</string>
|
<string name="grades_year_average_format">koniec roku: %s</string>
|
||||||
<string name="grades_year_average_percent_format">koniec roku: %s%%</string>
|
<string name="grades_year_average_percent_format">koniec roku: %s%%</string>
|
||||||
<string name="grades_year_average_point_format">koniec roku: %spkt</string>
|
<string name="grades_year_average_point_format">koniec roku: %spkt</string>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user