mirror of
https://github.com/szkolny-eu/szkolny-android.git
synced 2025-02-08 00:54:37 +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.db.entity.Grade
|
||||
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.SYNC_ALWAYS
|
||||
import pl.szczodrzynski.edziennik.data.db.enums.MetadataType
|
||||
@ -40,13 +41,13 @@ class UsosApiExamReports(
|
||||
tag = TAG,
|
||||
service = "examrep/user2",
|
||||
fields = listOf(
|
||||
"id",
|
||||
"type_description",
|
||||
"course_unit" to listOf("id", "course_name"),
|
||||
"sessions" to listOf(
|
||||
"number",
|
||||
"description",
|
||||
"issuer_grades" to listOf(
|
||||
"exam_id",
|
||||
"exam_session_number",
|
||||
"value_symbol",
|
||||
// "value_description",
|
||||
"passes",
|
||||
@ -93,6 +94,8 @@ class UsosApiExamReports(
|
||||
}
|
||||
|
||||
private fun processExamReport(termId: String, courseId: String, examReport: JsonObject) {
|
||||
val examId = examReport.getString("id")?.toIntOrNull()
|
||||
?: return
|
||||
val typeDescription = examReport.getLangString("type_description")
|
||||
val courseUnit = examReport.getJsonObject("course_unit")
|
||||
?: return
|
||||
@ -103,16 +106,26 @@ class UsosApiExamReports(
|
||||
val sessions = examReport.getJsonArray("sessions")
|
||||
?: 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) {
|
||||
if (!sessionEl.isJsonObject)
|
||||
continue
|
||||
val session = sessionEl.asJsonObject
|
||||
|
||||
val sessionNumber = session.getInt("number") ?: continue
|
||||
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 passes = issuerGrade.getBoolean("passes")
|
||||
val countsIntoAverage = issuerGrade.getString("counts_into_average") ?: "T"
|
||||
@ -121,8 +134,6 @@ class UsosApiExamReports(
|
||||
?.getLong("id") ?: -1L
|
||||
val comment = issuerGrade.getString("comment")
|
||||
|
||||
val gradeCategory = data.gradeCategories[courseUnitId]
|
||||
val classType = gradeCategory?.columns?.get(0)
|
||||
val value = valueSymbol.toFloatOrNull() ?: 0.0f
|
||||
|
||||
if (termId !in data.termNames) {
|
||||
@ -142,13 +153,10 @@ class UsosApiExamReports(
|
||||
comment = termId,
|
||||
semester = 1,
|
||||
teacherId = modificationAuthorId,
|
||||
subjectId = data.getSubject(
|
||||
id = null,
|
||||
name = courseName,
|
||||
shortName = courseId,
|
||||
).id,
|
||||
subjectId = subject.id,
|
||||
addedDate = Date.fromIso(dateModified),
|
||||
)
|
||||
hasGrade = true
|
||||
|
||||
if (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_TEXT = 31
|
||||
const val TYPE_TEXT = 40
|
||||
const val TYPE_NO_GRADE = 100
|
||||
}
|
||||
|
||||
@ColumnInfo(name = "gradeValueMax")
|
||||
|
@ -16,6 +16,7 @@ import kotlinx.coroutines.Job
|
||||
import pl.szczodrzynski.edziennik.App
|
||||
import pl.szczodrzynski.edziennik.R
|
||||
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.ext.onClick
|
||||
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)
|
||||
else
|
||||
holder.itemView.isEnabled = true
|
||||
} else {
|
||||
holder.itemView.setOnClickListener(null)
|
||||
holder.itemView.isEnabled = false
|
||||
}
|
||||
}
|
||||
|
||||
fun notifyItemChanged(model: Any) {
|
||||
|
@ -18,6 +18,7 @@ import com.mikepenz.iconics.typeface.library.community.material.CommunityMateria
|
||||
import kotlinx.coroutines.*
|
||||
import pl.szczodrzynski.edziennik.*
|
||||
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.full.GradeFull
|
||||
import pl.szczodrzynski.edziennik.databinding.GradesListFragmentBinding
|
||||
@ -305,18 +306,24 @@ class GradesListFragment : Fragment(), CoroutineScope {
|
||||
val semesterCount = mutableListOf<Float>()
|
||||
val totalSum = mutableListOf<Float>()
|
||||
val totalCount = mutableListOf<Float>()
|
||||
val ectsPoints = mutableMapOf<Long, Float>()
|
||||
val ectsPoints = mutableMapOf<Pair<Long, String?>, Float>()
|
||||
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)
|
||||
continue
|
||||
totalSum.add(grade.value * grade.weight)
|
||||
totalCount.add(grade.weight)
|
||||
|
||||
if (grade.value < 3.0)
|
||||
// exam not passed, reset points for this subject
|
||||
ectsPoints[grade.subjectId] = 0.0f
|
||||
else if (grade.subjectId !in ectsPoints)
|
||||
ectsPoints[pointsPair] = 0.0f
|
||||
else if (pointsPair !in ectsPoints)
|
||||
// no points for this subject, simply assign
|
||||
ectsPoints[grade.subjectId] = grade.weight
|
||||
ectsPoints[pointsPair] = grade.weight
|
||||
|
||||
if (filterTermId != null && grade.comment != filterTermId)
|
||||
continue
|
||||
|
@ -11,6 +11,7 @@ import androidx.core.view.isVisible
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import pl.szczodrzynski.edziennik.App
|
||||
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.databinding.GradesItemGradeBinding
|
||||
import pl.szczodrzynski.edziennik.ui.grades.GradesAdapter
|
||||
@ -59,6 +60,9 @@ class GradeViewHolder(
|
||||
b.gradeWeight.isVisible = weightText != null
|
||||
|
||||
b.gradeTeacherName.text = grade.teacherName
|
||||
if (grade.addedDate == 0L || grade.type == TYPE_NO_GRADE)
|
||||
b.gradeAddedDate.text = null
|
||||
else
|
||||
b.gradeAddedDate.text = Date.fromMillis(grade.addedDate).let {
|
||||
it.getRelativeString(app, 5) ?: it.formattedStringShort
|
||||
}
|
||||
|
@ -25,6 +25,7 @@ import kotlinx.coroutines.Job
|
||||
import pl.szczodrzynski.edziennik.App
|
||||
import pl.szczodrzynski.edziennik.MainActivity
|
||||
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.Subject
|
||||
import pl.szczodrzynski.edziennik.data.db.full.GradeFull
|
||||
@ -70,7 +71,7 @@ class HomeGradesCard(
|
||||
app.db.gradeDao().getAllFromDate(profile.id, sevenDaysAgo).observe(fragment, Observer {
|
||||
grades.apply {
|
||||
clear()
|
||||
addAll(it)
|
||||
addAll(it.filter { it.type != TYPE_NO_GRADE })
|
||||
}
|
||||
update()
|
||||
})
|
||||
|
@ -12,6 +12,7 @@ import pl.szczodrzynski.edziennik.App
|
||||
import pl.szczodrzynski.edziennik.R
|
||||
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_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_SUM
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_YEAR_FINAL
|
||||
@ -90,6 +91,7 @@ class GradesManager(val app: App) : CoroutineScope {
|
||||
else
|
||||
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_NO_GRADE -> context.getString(R.string.grades_weight_no_grade)
|
||||
else -> null
|
||||
}
|
||||
|
||||
|
@ -350,16 +350,14 @@
|
||||
android:layout_width="1dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginTop="8dp"
|
||||
android:background="@drawable/divider"
|
||||
android:visibility="gone" />
|
||||
android:background="@drawable/divider" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center_horizontal"
|
||||
android:orientation="vertical"
|
||||
android:visibility="gone">
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
|
@ -500,6 +500,7 @@
|
||||
<string name="grades_value_format">wartość: %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_no_grade">brak oceny</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_point_format">koniec roku: %spkt</string>
|
||||
|
Loading…
x
Reference in New Issue
Block a user