Add attendance summary statistics
This commit is contained in:
parent
1662b7ebbc
commit
17ad623d63
8 changed files with 172 additions and 20 deletions
|
@ -64,6 +64,8 @@ class Api {
|
||||||
|
|
||||||
fun getAttendance(startDate: Date? = null) = snp.getAttendance(startDate)
|
fun getAttendance(startDate: Date? = null) = snp.getAttendance(startDate)
|
||||||
|
|
||||||
|
fun getAttendanceSummary(subjectId: Int? = null) = snp.getAttendanceSummary(subjectId)
|
||||||
|
|
||||||
fun getExams(startDate: Date? = null) = snp.getExams(startDate)
|
fun getExams(startDate: Date? = null) = snp.getExams(startDate)
|
||||||
|
|
||||||
fun getGrades(semesterId: Int? = null) = snp.getGrades(semesterId)
|
fun getGrades(semesterId: Int? = null) = snp.getGrades(semesterId)
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
package io.github.wulkanowy.api.attendance
|
||||||
|
|
||||||
|
data class AttendanceSummary(
|
||||||
|
val month: String,
|
||||||
|
val presence: Int,
|
||||||
|
val absence: Int,
|
||||||
|
val absenceExcused: Int,
|
||||||
|
val absenceForSchoolReasons: Int,
|
||||||
|
val lateness: Int,
|
||||||
|
val latenessExcused: Int,
|
||||||
|
val exemption: Int
|
||||||
|
)
|
|
@ -0,0 +1,21 @@
|
||||||
|
package io.github.wulkanowy.api.attendance
|
||||||
|
|
||||||
|
import pl.droidsonroids.jspoon.annotation.Selector
|
||||||
|
|
||||||
|
class AttendanceSummaryResponse {
|
||||||
|
|
||||||
|
@Selector(".mainContainer > table thead th:not(:first-of-type):not(:last-of-type)")
|
||||||
|
var days: List<String> = emptyList()
|
||||||
|
|
||||||
|
@Selector(".mainContainer > table tbody tr")
|
||||||
|
var rows: List<AttendanceSummaryResponse.AttendanceRow> = emptyList()
|
||||||
|
|
||||||
|
class AttendanceRow {
|
||||||
|
|
||||||
|
@Selector("td", index = 0)
|
||||||
|
lateinit var name: String
|
||||||
|
|
||||||
|
@Selector("td:not(:first-of-type):not(:last-of-type)", defValue = "0")
|
||||||
|
var value: List<String> = emptyList()
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,7 @@
|
||||||
package io.github.wulkanowy.api.repository
|
package io.github.wulkanowy.api.repository
|
||||||
|
|
||||||
import io.github.wulkanowy.api.attendance.Attendance
|
import io.github.wulkanowy.api.attendance.Attendance
|
||||||
|
import io.github.wulkanowy.api.attendance.AttendanceSummary
|
||||||
import io.github.wulkanowy.api.exams.Exam
|
import io.github.wulkanowy.api.exams.Exam
|
||||||
import io.github.wulkanowy.api.grades.Grade
|
import io.github.wulkanowy.api.grades.Grade
|
||||||
import io.github.wulkanowy.api.grades.GradeSummary
|
import io.github.wulkanowy.api.grades.GradeSummary
|
||||||
|
@ -52,6 +53,22 @@ class StudentAndParentRepository(private val api: StudentAndParentService) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getAttendanceSummary(subjectId: Int?): Single<List<AttendanceSummary>> {
|
||||||
|
return api.getAttendanceSummary(subjectId).map { res ->
|
||||||
|
res.days.mapIndexed { i, day ->
|
||||||
|
AttendanceSummary(day,
|
||||||
|
res.rows[0].value[i].toIntOrNull() ?: 0,
|
||||||
|
res.rows[1].value[i].toIntOrNull() ?: 0,
|
||||||
|
res.rows[2].value[i].toIntOrNull() ?: 0,
|
||||||
|
res.rows[3].value[i].toIntOrNull() ?: 0,
|
||||||
|
res.rows[4].value[i].toIntOrNull() ?: 0,
|
||||||
|
res.rows[5].value[i].toIntOrNull() ?: 0,
|
||||||
|
res.rows[6].value[i].toIntOrNull() ?: 0
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun getExams(startDate: Date?): Single<List<Exam>> {
|
fun getExams(startDate: Date?): Single<List<Exam>> {
|
||||||
return api.getExams(startDate.toTick()).map { res ->
|
return api.getExams(startDate.toTick()).map { res ->
|
||||||
res.days.flatMap { day ->
|
res.days.flatMap { day ->
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package io.github.wulkanowy.api.service
|
package io.github.wulkanowy.api.service
|
||||||
|
|
||||||
import io.github.wulkanowy.api.attendance.AttendanceResponse
|
import io.github.wulkanowy.api.attendance.AttendanceResponse
|
||||||
|
import io.github.wulkanowy.api.attendance.AttendanceSummaryResponse
|
||||||
import io.github.wulkanowy.api.exams.ExamResponse
|
import io.github.wulkanowy.api.exams.ExamResponse
|
||||||
import io.github.wulkanowy.api.grades.GradesResponse
|
import io.github.wulkanowy.api.grades.GradesResponse
|
||||||
import io.github.wulkanowy.api.grades.GradesSummaryResponse
|
import io.github.wulkanowy.api.grades.GradesSummaryResponse
|
||||||
|
@ -33,6 +34,9 @@ interface StudentAndParentService {
|
||||||
@GET("Frekwencja.mvc")
|
@GET("Frekwencja.mvc")
|
||||||
fun getAttendance(@Query("data") date: String): Single<AttendanceResponse>
|
fun getAttendance(@Query("data") date: String): Single<AttendanceResponse>
|
||||||
|
|
||||||
|
@GET("Frekwencja.mvc")
|
||||||
|
fun getAttendanceSummary(@Query("idPrzedmiot") subjectId: Int?): Single<AttendanceSummaryResponse>
|
||||||
|
|
||||||
@GET("Sprawdziany.mvc/Terminarz?rodzajWidoku=2")
|
@GET("Sprawdziany.mvc/Terminarz?rodzajWidoku=2")
|
||||||
fun getExams(@Query("data") date: String): Single<ExamResponse>
|
fun getExams(@Query("data") date: String): Single<ExamResponse>
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package io.github.wulkanowy.api
|
package io.github.wulkanowy.api
|
||||||
|
|
||||||
import io.github.wulkanowy.api.attendance.Attendance
|
import io.github.wulkanowy.api.attendance.Attendance
|
||||||
|
import io.github.wulkanowy.api.attendance.AttendanceSummary
|
||||||
import io.github.wulkanowy.api.exams.Exam
|
import io.github.wulkanowy.api.exams.Exam
|
||||||
import io.github.wulkanowy.api.grades.Grade
|
import io.github.wulkanowy.api.grades.Grade
|
||||||
import io.github.wulkanowy.api.grades.GradeSummary
|
import io.github.wulkanowy.api.grades.GradeSummary
|
||||||
|
@ -28,9 +29,10 @@ import org.junit.Test
|
||||||
@Ignore
|
@Ignore
|
||||||
class ApiTest : BaseTest() {
|
class ApiTest : BaseTest() {
|
||||||
|
|
||||||
private var api = Api()
|
private var api = Api()
|
||||||
|
|
||||||
@Before fun setUp() {
|
@Before
|
||||||
|
fun setUp() {
|
||||||
api.apply {
|
api.apply {
|
||||||
logLevel = HttpLoggingInterceptor.Level.BASIC
|
logLevel = HttpLoggingInterceptor.Level.BASIC
|
||||||
ssl = true
|
ssl = true
|
||||||
|
@ -45,7 +47,8 @@ class ApiTest : BaseTest() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test fun schoolInfoTest() {
|
@Test
|
||||||
|
fun schoolInfoTest() {
|
||||||
val info = api.getSchoolInfo()
|
val info = api.getSchoolInfo()
|
||||||
val infoObserver = TestObserver<StudentAndParentResponse>()
|
val infoObserver = TestObserver<StudentAndParentResponse>()
|
||||||
info.subscribe(infoObserver)
|
info.subscribe(infoObserver)
|
||||||
|
@ -58,7 +61,8 @@ class ApiTest : BaseTest() {
|
||||||
assertEquals("Jan Kowalski", values.students[0].name)
|
assertEquals("Jan Kowalski", values.students[0].name)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test fun pupilsTest() {
|
@Test
|
||||||
|
fun pupilsTest() {
|
||||||
val pupils = api.getPupils()
|
val pupils = api.getPupils()
|
||||||
val pupilsObserver = TestObserver<List<Pupil>>()
|
val pupilsObserver = TestObserver<List<Pupil>>()
|
||||||
pupils.subscribe(pupilsObserver)
|
pupils.subscribe(pupilsObserver)
|
||||||
|
@ -74,7 +78,8 @@ class ApiTest : BaseTest() {
|
||||||
assertEquals("Publiczny dziennik Wulkanowego nr 1 w fakelog.cf", values[0].schoolName)
|
assertEquals("Publiczny dziennik Wulkanowego nr 1 w fakelog.cf", values[0].schoolName)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test fun semestersTest() {
|
@Test
|
||||||
|
fun semestersTest() {
|
||||||
val semesters = api.getSemesters()
|
val semesters = api.getSemesters()
|
||||||
val semestersObserver = TestObserver<List<Semester>>()
|
val semestersObserver = TestObserver<List<Semester>>()
|
||||||
semesters.subscribe(semestersObserver)
|
semesters.subscribe(semestersObserver)
|
||||||
|
@ -98,7 +103,8 @@ class ApiTest : BaseTest() {
|
||||||
assertEquals(2, values[5].semesterNumber)
|
assertEquals(2, values[5].semesterNumber)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test fun attendanceTest() {
|
@Test
|
||||||
|
fun attendanceTest() {
|
||||||
val attendance = api.getAttendance(getDate(2018, 9, 24))
|
val attendance = api.getAttendance(getDate(2018, 9, 24))
|
||||||
val attendanceObserver = TestObserver<List<Attendance>>()
|
val attendanceObserver = TestObserver<List<Attendance>>()
|
||||||
attendance.subscribe(attendanceObserver)
|
attendance.subscribe(attendanceObserver)
|
||||||
|
@ -126,7 +132,30 @@ class ApiTest : BaseTest() {
|
||||||
assertEquals(1, values[0].number)
|
assertEquals(1, values[0].number)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test fun examsTest() {
|
@Test
|
||||||
|
fun attendanceSummaryTest() {
|
||||||
|
val attendance = api.getAttendanceSummary()
|
||||||
|
val attendanceObserver = TestObserver<List<AttendanceSummary>>()
|
||||||
|
attendance.subscribe(attendanceObserver)
|
||||||
|
attendanceObserver.assertComplete()
|
||||||
|
|
||||||
|
val values = attendanceObserver.values()[0]
|
||||||
|
|
||||||
|
assertEquals(12, values.size)
|
||||||
|
|
||||||
|
assertEquals("IX", values[0].month)
|
||||||
|
assertEquals(32, values[0].presence)
|
||||||
|
assertEquals(1, values[0].absence)
|
||||||
|
assertEquals(2, values[0].absenceExcused)
|
||||||
|
assertEquals(3, values[0].absenceForSchoolReasons)
|
||||||
|
assertEquals(4, values[0].lateness)
|
||||||
|
assertEquals(5, values[0].latenessExcused)
|
||||||
|
assertEquals(6, values[0].exemption)
|
||||||
|
assertEquals(64, values[1].presence)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun examsTest() {
|
||||||
val exams = api.getExams(getDate(2018, 5, 28))
|
val exams = api.getExams(getDate(2018, 5, 28))
|
||||||
val examsObserver = TestObserver<List<Exam>>()
|
val examsObserver = TestObserver<List<Exam>>()
|
||||||
exams.subscribe(examsObserver)
|
exams.subscribe(examsObserver)
|
||||||
|
@ -144,7 +173,8 @@ class ApiTest : BaseTest() {
|
||||||
assertEquals("AZ", values[0].teacherSymbol)
|
assertEquals("AZ", values[0].teacherSymbol)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test fun homeworkTest() {
|
@Test
|
||||||
|
fun homeworkTest() {
|
||||||
val homework = api.getHomework(getDate(2017, 10, 23))
|
val homework = api.getHomework(getDate(2017, 10, 23))
|
||||||
val homeworkObserver = TestObserver<List<Homework>>()
|
val homeworkObserver = TestObserver<List<Homework>>()
|
||||||
homework.subscribe(homeworkObserver)
|
homework.subscribe(homeworkObserver)
|
||||||
|
@ -160,7 +190,8 @@ class ApiTest : BaseTest() {
|
||||||
assertEquals("TJ", values[1].teacherSymbol)
|
assertEquals("TJ", values[1].teacherSymbol)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test fun notesTest() {
|
@Test
|
||||||
|
fun notesTest() {
|
||||||
val notes = api.getNotes()
|
val notes = api.getNotes()
|
||||||
val notesObserver = TestObserver<List<Note>>()
|
val notesObserver = TestObserver<List<Note>>()
|
||||||
notes.subscribe(notesObserver)
|
notes.subscribe(notesObserver)
|
||||||
|
@ -174,7 +205,8 @@ class ApiTest : BaseTest() {
|
||||||
assertEquals("+ 20p za udział w Konkursie Języka Angielskiego", values[0].content)
|
assertEquals("+ 20p za udział w Konkursie Języka Angielskiego", values[0].content)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test fun gradesTest() {
|
@Test
|
||||||
|
fun gradesTest() {
|
||||||
val grades = api.getGrades(864)
|
val grades = api.getGrades(864)
|
||||||
val gradesObserver = TestObserver<List<Grade>>()
|
val gradesObserver = TestObserver<List<Grade>>()
|
||||||
grades.subscribe(gradesObserver)
|
grades.subscribe(gradesObserver)
|
||||||
|
@ -196,7 +228,8 @@ class ApiTest : BaseTest() {
|
||||||
assertEquals("", values[5].description)
|
assertEquals("", values[5].description)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test fun gradesSummaryTest() {
|
@Test
|
||||||
|
fun gradesSummaryTest() {
|
||||||
val summary = api.getGradesSummary(864)
|
val summary = api.getGradesSummary(864)
|
||||||
val summaryObserver = TestObserver<List<GradeSummary>>()
|
val summaryObserver = TestObserver<List<GradeSummary>>()
|
||||||
summary.subscribe(summaryObserver)
|
summary.subscribe(summaryObserver)
|
||||||
|
@ -217,7 +250,8 @@ class ApiTest : BaseTest() {
|
||||||
assertEquals("", values[8].final)
|
assertEquals("", values[8].final)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test fun teachersTest() {
|
@Test
|
||||||
|
fun teachersTest() {
|
||||||
val teachers = api.getTeachers()
|
val teachers = api.getTeachers()
|
||||||
val teachersObserver = TestObserver<List<Teacher>>()
|
val teachersObserver = TestObserver<List<Teacher>>()
|
||||||
teachers.subscribe(teachersObserver)
|
teachers.subscribe(teachersObserver)
|
||||||
|
@ -230,7 +264,8 @@ class ApiTest : BaseTest() {
|
||||||
assertEquals("TJ", values[1].short)
|
assertEquals("TJ", values[1].short)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test fun studentInfoTest() {
|
@Test
|
||||||
|
fun studentInfoTest() {
|
||||||
val student = api.getStudentInfo()
|
val student = api.getStudentInfo()
|
||||||
val studentObserver = TestObserver<StudentInfo>()
|
val studentObserver = TestObserver<StudentInfo>()
|
||||||
student.subscribe(studentObserver)
|
student.subscribe(studentObserver)
|
||||||
|
@ -263,7 +298,8 @@ class ApiTest : BaseTest() {
|
||||||
assertEquals("-", values.family[1].email)
|
assertEquals("-", values.family[1].email)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test fun messagesTest() {
|
@Test
|
||||||
|
fun messagesTest() {
|
||||||
val units = api.getReportingUnits()
|
val units = api.getReportingUnits()
|
||||||
val unitsObserver = TestObserver<List<ReportingUnit>>()
|
val unitsObserver = TestObserver<List<ReportingUnit>>()
|
||||||
units.subscribe(unitsObserver)
|
units.subscribe(unitsObserver)
|
||||||
|
@ -305,7 +341,8 @@ class ApiTest : BaseTest() {
|
||||||
assertEquals(1, mObserver.values().size)
|
assertEquals(1, mObserver.values().size)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test fun devicesTest() {
|
@Test
|
||||||
|
fun devicesTest() {
|
||||||
val devices = api.getRegisteredDevices()
|
val devices = api.getRegisteredDevices()
|
||||||
val devicesObserver = TestObserver<List<Device>>()
|
val devicesObserver = TestObserver<List<Device>>()
|
||||||
devices.subscribe(devicesObserver)
|
devices.subscribe(devicesObserver)
|
||||||
|
@ -316,7 +353,8 @@ class ApiTest : BaseTest() {
|
||||||
assertEquals(2, values.size)
|
assertEquals(2, values.size)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test fun tokenTest() {
|
@Test
|
||||||
|
fun tokenTest() {
|
||||||
val token = api.getToken()
|
val token = api.getToken()
|
||||||
val tokenObserver = TestObserver<TokenResponse>()
|
val tokenObserver = TestObserver<TokenResponse>()
|
||||||
token.subscribe(tokenObserver)
|
token.subscribe(tokenObserver)
|
||||||
|
@ -327,7 +365,8 @@ class ApiTest : BaseTest() {
|
||||||
assertEquals("999999", tokenObserver.values()[0].pin)
|
assertEquals("999999", tokenObserver.values()[0].pin)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test fun unregisterTest() {
|
@Test
|
||||||
|
fun unregisterTest() {
|
||||||
val unregister = api.unregisterDevice(1234)
|
val unregister = api.unregisterDevice(1234)
|
||||||
val unregisterObserver = TestObserver<List<Device>>()
|
val unregisterObserver = TestObserver<List<Device>>()
|
||||||
unregister.subscribe(unregisterObserver)
|
unregister.subscribe(unregisterObserver)
|
||||||
|
@ -336,7 +375,8 @@ class ApiTest : BaseTest() {
|
||||||
assertEquals(2, unregisterObserver.values()[0].size)
|
assertEquals(2, unregisterObserver.values()[0].size)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test fun timetableTest() {
|
@Test
|
||||||
|
fun timetableTest() {
|
||||||
val timetable = api.getTimetable(getDate(2018, 9, 17))
|
val timetable = api.getTimetable(getDate(2018, 9, 17))
|
||||||
val timetableObserver = TestObserver<List<Timetable>>()
|
val timetableObserver = TestObserver<List<Timetable>>()
|
||||||
timetable.subscribe(timetableObserver)
|
timetable.subscribe(timetableObserver)
|
||||||
|
@ -352,7 +392,8 @@ class ApiTest : BaseTest() {
|
||||||
assertEquals(false, values[0].changes)
|
assertEquals(false, values[0].changes)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test fun realizedTest() {
|
@Test
|
||||||
|
fun realizedTest() {
|
||||||
val realized = api.getRealized(getDate(2018, 9, 17))
|
val realized = api.getRealized(getDate(2018, 9, 17))
|
||||||
val realizedObserver = TestObserver<List<Realized>>()
|
val realizedObserver = TestObserver<List<Realized>>()
|
||||||
realized.subscribe(realizedObserver)
|
realized.subscribe(realizedObserver)
|
||||||
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
package io.github.wulkanowy.api.attendance
|
||||||
|
|
||||||
|
import io.github.wulkanowy.api.BaseTest
|
||||||
|
import org.junit.Assert.assertEquals
|
||||||
|
import org.junit.Test
|
||||||
|
|
||||||
|
class AttendanceSummaryTest : BaseTest() {
|
||||||
|
|
||||||
|
private val table by lazy {
|
||||||
|
getSnpRepo(AttendanceSummaryTest::class.java, "Frekwencja.html").getAttendanceSummary(-1).blockingGet()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun getAttendanceSummary() {
|
||||||
|
assertEquals(12, table.size)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun getAttendanceSummary_month() {
|
||||||
|
assertEquals("IX", table[0].month)
|
||||||
|
assertEquals("X", table[1].month)
|
||||||
|
assertEquals("XI", table[2].month)
|
||||||
|
assertEquals("VIII", table[11].month)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun getAttendanceSummary_presence() {
|
||||||
|
assertEquals(135, table[0].presence)
|
||||||
|
assertEquals(103, table[1].presence)
|
||||||
|
assertEquals(108, table[2].presence)
|
||||||
|
assertEquals(54, table[3].presence)
|
||||||
|
assertEquals(37, table[4].presence)
|
||||||
|
assertEquals(100, table[5].presence)
|
||||||
|
assertEquals(33, table[6].presence)
|
||||||
|
assertEquals(90, table[7].presence)
|
||||||
|
assertEquals(103, table[8].presence)
|
||||||
|
assertEquals(59, table[9].presence)
|
||||||
|
assertEquals(0, table[10].presence)
|
||||||
|
assertEquals(0, table[11].presence)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun getAttendanceSummary_absence() {
|
||||||
|
assertEquals(0, table[0].absence)
|
||||||
|
assertEquals(2, table[5].absence)
|
||||||
|
assertEquals(4, table[9].absence)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun getAttendanceSummary_exemption() {
|
||||||
|
assertEquals(0, table[0].exemption)
|
||||||
|
assertEquals(1, table[1].exemption)
|
||||||
|
assertEquals(0, table[9].exemption)
|
||||||
|
}
|
||||||
|
}
|
|
@ -276,6 +276,6 @@
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</main>
|
</main>
|
||||||
<footer>wersja: 17.07.0002.24480</footer>
|
<footer>wersja: 18.04.0003.29139</footer>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
Loading…
Reference in a new issue