[DB] Refactor database and entities.

This commit is contained in:
Kuba Szczodrzyński 2020-04-29 15:14:45 +02:00
parent 13a3f66db3
commit 3f61ab8299
144 changed files with 1788 additions and 1492 deletions

View File

@ -66,6 +66,7 @@ class App : MultiDexApplication(), Configuration.Provider, CoroutineScope {
val timetableManager by lazy { TimetableManager(this) } val timetableManager by lazy { TimetableManager(this) }
val eventManager by lazy { EventManager(this) } val eventManager by lazy { EventManager(this) }
val permissionManager by lazy { PermissionManager(this) } val permissionManager by lazy { PermissionManager(this) }
val attendanceManager by lazy { AttendanceManager(this) }
val db val db
get() = App.db get() = App.db

View File

@ -68,6 +68,9 @@ object Regexes {
} }
val MOBIDZIENNIK_ATTENDANCE_TYPES by lazy {
"""Legenda:.+?normal;">(.+?)</span>""".toRegex(DOT_MATCHES_ALL)
}
val MOBIDZIENNIK_ATTENDANCE_TABLE by lazy { val MOBIDZIENNIK_ATTENDANCE_TABLE by lazy {
"""<table .+?id="obecnosci_tabela">(.+?)</table>""".toRegex(DOT_MATCHES_ALL) """<table .+?id="obecnosci_tabela">(.+?)</table>""".toRegex(DOT_MATCHES_ALL)
} }

View File

@ -45,24 +45,25 @@ class EdudziennikWebAnnouncements(override val data: DataEdudziennik,
val addedDate = Date.fromIsoHm(dateString) val addedDate = Date.fromIsoHm(dateString)
val announcementObject = Announcement( val announcementObject = Announcement(
profileId, profileId = profileId,
id, id = id,
subject, subject = subject,
null, text = null,
startDate, startDate = startDate,
null, endDate = null,
teacher.id, teacherId = teacher.id,
longId addedDate = addedDate
) ).also {
it.idString = longId
}
data.announcementIgnoreList.add(announcementObject) data.announcementList.add(announcementObject)
data.metadataList.add(Metadata( data.metadataList.add(Metadata(
profileId, profileId,
Metadata.TYPE_ANNOUNCEMENT, Metadata.TYPE_ANNOUNCEMENT,
id, id,
profile.empty, profile.empty,
profile.empty, profile.empty
addedDate
)) ))
} }
} }

View File

@ -39,12 +39,12 @@ class EdudziennikWebAttendance(override val data: DataEdudziennik,
val attendanceTypes = EDUDZIENNIK_ATTENDANCE_TYPES.find(text)?.get(1)?.split(',')?.map { val attendanceTypes = EDUDZIENNIK_ATTENDANCE_TYPES.find(text)?.get(1)?.split(',')?.map {
val type = EDUDZIENNIK_ATTENDANCE_TYPE.find(it.trim()) val type = EDUDZIENNIK_ATTENDANCE_TYPE.find(it.trim())
val symbol = type?.get(1)?.trim() val symbol = type?.get(1)?.trim() ?: "?"
val name = type?.get(2)?.trim() val name = type?.get(2)?.trim() ?: "nieznany rodzaj"
return@map Triple( return@map Triple(
symbol, symbol,
name, name,
when (name?.toLowerCase(Locale.ROOT)) { when (name.toLowerCase(Locale.ROOT)) {
"obecność" -> Attendance.TYPE_PRESENT "obecność" -> Attendance.TYPE_PRESENT
"nieobecność" -> Attendance.TYPE_ABSENT "nieobecność" -> Attendance.TYPE_ABSENT
"spóźnienie" -> Attendance.TYPE_BELATED "spóźnienie" -> Attendance.TYPE_BELATED
@ -52,7 +52,7 @@ class EdudziennikWebAttendance(override val data: DataEdudziennik,
"dzień wolny" -> Attendance.TYPE_DAY_FREE "dzień wolny" -> Attendance.TYPE_DAY_FREE
"brak zajęć" -> Attendance.TYPE_DAY_FREE "brak zajęć" -> Attendance.TYPE_DAY_FREE
"oddelegowany" -> Attendance.TYPE_RELEASED "oddelegowany" -> Attendance.TYPE_RELEASED
else -> Attendance.TYPE_CUSTOM else -> Attendance.TYPE_UNKNOWN
} }
) )
} ?: emptyList() } ?: emptyList()
@ -62,38 +62,42 @@ class EdudziennikWebAttendance(override val data: DataEdudziennik,
val lessonNumber = attendanceElement[2].toInt() val lessonNumber = attendanceElement[2].toInt()
val attendanceSymbol = attendanceElement[3] val attendanceSymbol = attendanceElement[3]
val lessons = data.app.db.timetableDao().getForDateNow(profileId, date) val lessons = data.app.db.timetableDao().getAllForDateNow(profileId, date)
val lesson = lessons.firstOrNull { it.lessonNumber == lessonNumber } val lesson = lessons.firstOrNull { it.lessonNumber == lessonNumber }
val id = "${date.stringY_m_d}:$lessonNumber:$attendanceSymbol".crc32() val id = "${date.stringY_m_d}:$lessonNumber:$attendanceSymbol".crc32()
val (_, name, type) = attendanceTypes.firstOrNull { (symbol, _, _) -> symbol == attendanceSymbol } val (typeSymbol, typeName, baseType) = attendanceTypes.firstOrNull { (symbol, _, _) -> symbol == attendanceSymbol }
?: return@forEach ?: return@forEach
val startTime = data.lessonRanges.singleOrNull { it.lessonNumber == lessonNumber }?.startTime val startTime = data.lessonRanges.singleOrNull { it.lessonNumber == lessonNumber }?.startTime
?: return@forEach ?: return@forEach
val attendanceObject = Attendance( val attendanceObject = Attendance(
profileId, profileId = profileId,
id, id = id,
lesson?.displayTeacherId ?: -1, baseType = baseType,
lesson?.displaySubjectId ?: -1, typeName = typeName,
profile.currentSemester, typeShort = data.app.attendanceManager.getTypeShort(baseType),
name, typeSymbol = typeSymbol,
date, typeColor = null,
lesson?.displayStartTime ?: startTime, date = date,
type startTime = lesson?.displayStartTime ?: startTime,
) semester = profile.currentSemester,
teacherId = lesson?.displayTeacherId ?: -1,
subjectId = lesson?.displaySubjectId ?: -1
).also {
it.lessonNumber = lessonNumber
}
data.attendanceList.add(attendanceObject) data.attendanceList.add(attendanceObject)
if(type != Attendance.TYPE_PRESENT) { if (baseType != Attendance.TYPE_PRESENT) {
data.metadataList.add(Metadata( data.metadataList.add(Metadata(
profileId, profileId,
Metadata.TYPE_ATTENDANCE, Metadata.TYPE_ATTENDANCE,
id, id,
profile.empty, profile.empty,
profile.empty, profile.empty
System.currentTimeMillis()
)) ))
} }
} }

View File

@ -57,8 +57,7 @@ class EdudziennikWebEvents(override val data: DataEdudziennik,
Metadata.TYPE_EVENT, Metadata.TYPE_EVENT,
id, id,
profile.empty, profile.empty,
profile.empty, profile.empty
System.currentTimeMillis()
)) ))
} }

View File

@ -46,7 +46,7 @@ class EdudziennikWebExams(override val data: DataEdudziennik,
if (dateString.isBlank()) return@forEach if (dateString.isBlank()) return@forEach
val date = Date.fromY_m_d(dateString) val date = Date.fromY_m_d(dateString)
val lessons = data.app.db.timetableDao().getForDateNow(profileId, date) val lessons = data.app.db.timetableDao().getAllForDateNow(profileId, date)
val startTime = lessons.firstOrNull { it.displaySubjectId == subject.id }?.displayStartTime val startTime = lessons.firstOrNull { it.displaySubjectId == subject.id }?.displayStartTime
val eventTypeElement = examElement.child(3).child(0) val eventTypeElement = examElement.child(3).child(0)
@ -74,8 +74,7 @@ class EdudziennikWebExams(override val data: DataEdudziennik,
Metadata.TYPE_EVENT, Metadata.TYPE_EVENT,
id, id,
profile.empty, profile.empty,
profile.empty, profile.empty
System.currentTimeMillis()
)) ))
} }

View File

@ -126,7 +126,8 @@ class EdudziennikWebGrades(override val data: DataEdudziennik,
comment = null, comment = null,
semester = semester, semester = semester,
teacherId = teacher.id, teacherId = teacher.id,
subjectId = subject.id subjectId = subject.id,
addedDate = addedDate
) )
data.gradeList.add(gradeObject) data.gradeList.add(gradeObject)
@ -135,8 +136,7 @@ class EdudziennikWebGrades(override val data: DataEdudziennik,
Metadata.TYPE_GRADE, Metadata.TYPE_GRADE,
id, id,
profile.empty, profile.empty,
profile.empty, profile.empty
addedDate
)) ))
} }
@ -168,8 +168,7 @@ class EdudziennikWebGrades(override val data: DataEdudziennik,
Metadata.TYPE_GRADE, Metadata.TYPE_GRADE,
proposedGradeObject.id, proposedGradeObject.id,
profile.empty, profile.empty,
profile.empty, profile.empty
System.currentTimeMillis()
)) ))
} }
@ -201,8 +200,7 @@ class EdudziennikWebGrades(override val data: DataEdudziennik,
Metadata.TYPE_GRADE, Metadata.TYPE_GRADE,
finalGradeObject.id, finalGradeObject.id,
profile.empty, profile.empty,
profile.empty, profile.empty
System.currentTimeMillis()
)) ))
} }
} }

View File

@ -43,7 +43,7 @@ class EdudziennikWebHomework(override val data: DataEdudziennik,
val subjectName = subjectElement.text() val subjectName = subjectElement.text()
val subject = data.getSubject(subjectId, subjectName) val subject = data.getSubject(subjectId, subjectName)
val lessons = data.app.db.timetableDao().getForDateNow(profileId, date) val lessons = data.app.db.timetableDao().getAllForDateNow(profileId, date)
val startTime = lessons.firstOrNull { it.subjectId == subject.id }?.displayStartTime val startTime = lessons.firstOrNull { it.subjectId == subject.id }?.displayStartTime
val teacherName = homeworkElement.child(2).text() val teacherName = homeworkElement.child(2).text()
@ -72,8 +72,7 @@ class EdudziennikWebHomework(override val data: DataEdudziennik,
Metadata.TYPE_HOMEWORK, Metadata.TYPE_HOMEWORK,
id, id,
profile.empty, profile.empty,
profile.empty, profile.empty
System.currentTimeMillis()
)) ))
} }
} }

View File

@ -24,9 +24,9 @@ class EdudziennikWebLuckyNumber(override val data: DataEdudziennik,
webGet(TAG, data.schoolEndpoint + "Lucky", xhr = true) { text -> webGet(TAG, data.schoolEndpoint + "Lucky", xhr = true) { text ->
text.toIntOrNull()?.also { luckyNumber -> text.toIntOrNull()?.also { luckyNumber ->
val luckyNumberObject = LuckyNumber( val luckyNumberObject = LuckyNumber(
profileId, profileId = profileId,
Date.getToday(), date = Date.getToday(),
luckyNumber number = luckyNumber
) )
data.luckyNumberList.add(luckyNumberObject) data.luckyNumberList.add(luckyNumberObject)
@ -35,8 +35,7 @@ class EdudziennikWebLuckyNumber(override val data: DataEdudziennik,
Metadata.TYPE_LUCKY_NUMBER, Metadata.TYPE_LUCKY_NUMBER,
luckyNumberObject.date.value.toLong(), luckyNumberObject.date.value.toLong(),
true, true,
profile.empty, profile.empty
System.currentTimeMillis()
)) ))
} }

View File

@ -41,12 +41,15 @@ class EdudziennikWebNotes(override val data: DataEdudziennik,
val description = noteElement.child(3).text() val description = noteElement.child(3).text()
val noticeObject = Notice( val noticeObject = Notice(
profileId, profileId = profileId,
id, id = id,
description, type = Notice.TYPE_NEUTRAL,
profile.currentSemester, semester = profile.currentSemester,
Notice.TYPE_NEUTRAL, text = description,
teacher.id category = null,
points = null,
teacherId = teacher.id,
addedDate = addedDate
) )
data.noticeList.add(noticeObject) data.noticeList.add(noticeObject)
@ -55,8 +58,7 @@ class EdudziennikWebNotes(override val data: DataEdudziennik,
Metadata.TYPE_NOTICE, Metadata.TYPE_NOTICE,
id, id,
profile.empty, profile.empty,
profile.empty, profile.empty
addedDate
)) ))
} }

View File

@ -124,8 +124,7 @@ class EdudziennikWebTimetable(override val data: DataEdudziennik,
Metadata.TYPE_LESSON_CHANGE, Metadata.TYPE_LESSON_CHANGE,
lessonObject.id, lessonObject.id,
seen, seen,
seen, seen
System.currentTimeMillis()
)) ))
} }
} }

View File

@ -68,9 +68,9 @@ class IdziennikApiCurrentRegister(override val data: DataIdziennik,
val luckyNumberObject = LuckyNumber( val luckyNumberObject = LuckyNumber(
data.profileId, profileId = data.profileId,
luckyNumberDate, date = luckyNumberDate,
luckyNumber number = luckyNumber
) )
data.luckyNumberList.add(luckyNumberObject) data.luckyNumberList.add(luckyNumberObject)
@ -80,8 +80,7 @@ class IdziennikApiCurrentRegister(override val data: DataIdziennik,
Metadata.TYPE_LUCKY_NUMBER, Metadata.TYPE_LUCKY_NUMBER,
luckyNumberObject.date.value.toLong(), luckyNumberObject.date.value.toLong(),
true, true,
data.profile?.empty ?: false, data.profile?.empty ?: false
System.currentTimeMillis()
)) ))
} }

View File

@ -69,7 +69,8 @@ class IdziennikApiMessagesInbox(override val data: DataIdziennik,
type = if (jMessage.getBoolean("rekordUsuniety") == true) TYPE_DELETED else TYPE_RECEIVED, type = if (jMessage.getBoolean("rekordUsuniety") == true) TYPE_DELETED else TYPE_RECEIVED,
subject = subject, subject = subject,
body = body, body = body,
senderId = rTeacher.id senderId = rTeacher.id,
addedDate = sentDate
) )
val messageRecipient = MessageRecipient( val messageRecipient = MessageRecipient(
@ -87,8 +88,7 @@ class IdziennikApiMessagesInbox(override val data: DataIdziennik,
Metadata.TYPE_MESSAGE, Metadata.TYPE_MESSAGE,
message.id, message.id,
readDate > 0, readDate > 0,
readDate > 0 || profile?.empty ?: false, readDate > 0 || profile?.empty ?: false
sentDate
)) ))
} }

View File

@ -51,7 +51,8 @@ class IdziennikApiMessagesSent(override val data: DataIdziennik,
type = TYPE_SENT, type = TYPE_SENT,
subject = subject, subject = subject,
body = body, body = body,
senderId = null senderId = null,
addedDate = sentDate
) )
for (recipientEl in jMessage.getAsJsonArray("odbiorcy")) { for (recipientEl in jMessage.getAsJsonArray("odbiorcy")) {
@ -76,7 +77,7 @@ class IdziennikApiMessagesSent(override val data: DataIdziennik,
} }
data.messageList.add(message) data.messageList.add(message)
data.metadataList.add(Metadata(profileId, Metadata.TYPE_MESSAGE, message.id, true, true, sentDate)) data.metadataList.add(Metadata(profileId, Metadata.TYPE_MESSAGE, message.id, true, true))
} }
data.setSyncNext(ENDPOINT_IDZIENNIK_API_MESSAGES_SENT, DAY, DRAWER_ITEM_MESSAGES) data.setSyncNext(ENDPOINT_IDZIENNIK_API_MESSAGES_SENT, DAY, DRAWER_ITEM_MESSAGES)

View File

@ -52,14 +52,14 @@ class IdziennikWebAnnouncements(override val data: DataIdziennik,
val startDate = jAnnouncement.getString("DataWydarzenia")?.replace("[^\\d]".toRegex(), "")?.toLongOrNull()?.let { Date.fromMillis(it) } val startDate = jAnnouncement.getString("DataWydarzenia")?.replace("[^\\d]".toRegex(), "")?.toLongOrNull()?.let { Date.fromMillis(it) }
val announcementObject = Announcement( val announcementObject = Announcement(
profileId, profileId = profileId,
announcementId, id = announcementId,
jAnnouncement.get("Temat").asString, subject = jAnnouncement.get("Temat").asString,
jAnnouncement.get("Tresc").asString, text = jAnnouncement.get("Tresc").asString,
startDate, startDate = startDate,
null, endDate = null,
rTeacher.id, teacherId = rTeacher.id,
null addedDate = addedDate
) )
data.announcementList.add(announcementObject) data.announcementList.add(announcementObject)
data.metadataList.add(Metadata( data.metadataList.add(Metadata(
@ -67,8 +67,7 @@ class IdziennikWebAnnouncements(override val data: DataIdziennik,
Metadata.TYPE_ANNOUNCEMENT, Metadata.TYPE_ANNOUNCEMENT,
announcementObject.id, announcementObject.id,
profile?.empty ?: false, profile?.empty ?: false,
profile?.empty ?: false, profile?.empty ?: false
addedDate
)) ))
} }

View File

@ -12,10 +12,18 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.ENDPOINT_IDZIENNI
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.IdziennikWeb import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.IdziennikWeb
import pl.szczodrzynski.edziennik.data.api.models.ApiError import pl.szczodrzynski.edziennik.data.api.models.ApiError
import pl.szczodrzynski.edziennik.data.db.entity.Attendance import pl.szczodrzynski.edziennik.data.db.entity.Attendance
import pl.szczodrzynski.edziennik.data.db.entity.Attendance.* import pl.szczodrzynski.edziennik.data.db.entity.Attendance.Companion.TYPE_ABSENT
import pl.szczodrzynski.edziennik.data.db.entity.Attendance.Companion.TYPE_ABSENT_EXCUSED
import pl.szczodrzynski.edziennik.data.db.entity.Attendance.Companion.TYPE_BELATED
import pl.szczodrzynski.edziennik.data.db.entity.Attendance.Companion.TYPE_PRESENT
import pl.szczodrzynski.edziennik.data.db.entity.Attendance.Companion.TYPE_PRESENT_CUSTOM
import pl.szczodrzynski.edziennik.data.db.entity.Attendance.Companion.TYPE_RELEASED
import pl.szczodrzynski.edziennik.data.db.entity.Attendance.Companion.TYPE_UNKNOWN
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.getInt
import pl.szczodrzynski.edziennik.getJsonObject import pl.szczodrzynski.edziennik.getJsonObject
import pl.szczodrzynski.edziennik.getString
import pl.szczodrzynski.edziennik.utils.models.Date import pl.szczodrzynski.edziennik.utils.models.Date
import pl.szczodrzynski.edziennik.utils.models.Time import pl.szczodrzynski.edziennik.utils.models.Time
@ -51,71 +59,97 @@ class IdziennikWebAttendance(override val data: DataIdziennik,
for (jAttendanceEl in json.getAsJsonArray("Obecnosci")) { for (jAttendanceEl in json.getAsJsonArray("Obecnosci")) {
val jAttendance = jAttendanceEl.asJsonObject val jAttendance = jAttendanceEl.asJsonObject
// jAttendance // jAttendance
val attendanceTypeIdziennik = jAttendance.get("TypObecnosci").asInt val type = jAttendance.get("TypObecnosci").asInt
if (attendanceTypeIdziennik == 5 || attendanceTypeIdziennik == 7)
continue // skip "zajęcia nie odbyły się" and "Ferie"
val attendanceDate = Date.fromY_m_d(jAttendance.get("Data").asString) if (type == 5 || type == 7)
val attendanceTime = Time.fromH_m(jAttendance.get("OdDoGodziny").asString)
if (attendanceDate.combineWith(attendanceTime) > System.currentTimeMillis())
continue continue
val attendanceId = jAttendance.get("IdLesson").asString.crc16().toLong() val date = Date.fromY_m_d(jAttendance.get("Data").asString)
val time = Time.fromH_m(jAttendance.get("OdDoGodziny").asString)
if (date.combineWith(time) > System.currentTimeMillis())
continue
val id = jAttendance.get("IdLesson").asString.crc16().toLong()
val rSubject = data.getSubject(jAttendance.get("Przedmiot").asString, jAttendance.get("IdPrzedmiot").asLong, "") val rSubject = data.getSubject(jAttendance.get("Przedmiot").asString, jAttendance.get("IdPrzedmiot").asLong, "")
val rTeacher = data.getTeacherByFDotSpaceLast(jAttendance.get("PrzedmiotNauczyciel").asString) val rTeacher = data.getTeacherByFDotSpaceLast(jAttendance.get("PrzedmiotNauczyciel").asString)
var attendanceName = "obecność" var baseType = TYPE_UNKNOWN
var attendanceType = Attendance.TYPE_CUSTOM var typeName = "nieznany rodzaj"
var typeSymbol: String? = null
var typeColor: Long? = null
when (attendanceTypeIdziennik) { /* https://iuczniowie.progman.pl/idziennik/mod_panelRodzica/obecnosci/obecnosciUcznia_lmt637231494660000000.js */
1 /* nieobecność usprawiedliwiona */ -> { /* https://iuczniowie.progman.pl/idziennik/mod_panelRodzica/obecnosci/obecnosci_lmt637231494660000000.css */
attendanceName = "nieobecność usprawiedliwiona" when (type) {
attendanceType = TYPE_ABSENT_EXCUSED 1 -> {
baseType = TYPE_ABSENT_EXCUSED
typeName = "nieobecność usprawiedliwiona"
typeColor = 0xffffe099
} }
2 /* spóźnienie */ -> { 2 -> {
attendanceName = "spóźnienie" baseType = TYPE_BELATED
attendanceType = TYPE_BELATED typeName = "spóźnienie"
typeColor = 0xffffffaa
} }
3 /* nieobecność nieusprawiedliwiona */ -> { 3 -> {
attendanceName = "nieobecność nieusprawiedliwiona" baseType = TYPE_ABSENT
attendanceType = TYPE_ABSENT typeName = "nieobecność nieusprawiedliwiona"
typeColor = 0xffffad99
} }
4 /* zwolnienie */, 9 /* zwolniony / obecny */ -> { 4, 9 -> {
attendanceType = TYPE_RELEASED baseType = TYPE_RELEASED
if (attendanceTypeIdziennik == 4) if (type == 4) {
attendanceName = "zwolnienie" typeName = "zwolnienie"
if (attendanceTypeIdziennik == 9) typeColor = 0xffa8beff
attendanceName = "zwolnienie / obecność"
} }
0 /* obecny */, 8 /* Wycieczka */ -> { if (type == 9) {
attendanceType = TYPE_PRESENT typeName = "zwolniony / obecny"
if (attendanceTypeIdziennik == 8) typeSymbol = "zb"
attendanceName = "wycieczka" typeColor = 0xffff69b4
}
}
8 -> {
baseType = TYPE_PRESENT_CUSTOM
typeName = "wycieczka"
typeSymbol = "w"
typeColor = null
}
0 -> {
baseType = TYPE_PRESENT
typeName = "obecny"
typeColor = 0xffccffcc
} }
} }
val semester = profile?.dateToSemester(attendanceDate) ?: 1 val semester = profile?.dateToSemester(date) ?: 1
val attendanceObject = Attendance( val attendanceObject = Attendance(
profileId, profileId = profileId,
attendanceId, id = id,
rTeacher.id, baseType = baseType,
rSubject.id, typeName = typeName,
semester, typeShort = typeSymbol ?: data.app.attendanceManager.getTypeShort(baseType),
attendanceName, typeSymbol = typeSymbol ?: data.app.attendanceManager.getTypeShort(baseType),
attendanceDate, typeColor = typeColor?.toInt(),
attendanceTime, date = date,
attendanceType startTime = time,
) semester = semester,
teacherId = rTeacher.id,
subjectId = rSubject.id
).also {
it.lessonTopic = jAttendance.getString("PrzedmiotTemat")
it.lessonNumber = jAttendance.getInt("Godzina")
}
data.attendanceList.add(attendanceObject) data.attendanceList.add(attendanceObject)
if (attendanceObject.type != TYPE_PRESENT) { if (attendanceObject.baseType != TYPE_PRESENT) {
data.metadataList.add(Metadata( data.metadataList.add(Metadata(
profileId, profileId,
Metadata.TYPE_ATTENDANCE, Metadata.TYPE_ATTENDANCE,
attendanceObject.id, attendanceObject.id,
profile?.empty ?: false, profile?.empty ?: false,
profile?.empty ?: false, profile?.empty ?: false
System.currentTimeMillis()
)) ))
} }
} }

View File

@ -68,7 +68,7 @@ class IdziennikWebExams(override val data: DataIdziennik,
val teacherId = data.getTeacherByLastFirst(teacherName).id val teacherId = data.getTeacherByLastFirst(teacherName).id
val topic = exam.getString("zakres")?.trim() ?: "" val topic = exam.getString("zakres")?.trim() ?: ""
val lessonList = data.db.timetableDao().getForDateNow(profileId, examDate) val lessonList = data.db.timetableDao().getAllForDateNow(profileId, examDate)
val startTime = lessonList.firstOrNull { it.subjectId == subjectId }?.startTime val startTime = lessonList.firstOrNull { it.subjectId == subjectId }?.startTime
val eventType = when (exam.getString("rodzaj")?.toLowerCase(Locale.getDefault())) { val eventType = when (exam.getString("rodzaj")?.toLowerCase(Locale.getDefault())) {
@ -98,8 +98,7 @@ class IdziennikWebExams(override val data: DataIdziennik,
Metadata.TYPE_EVENT, Metadata.TYPE_EVENT,
eventObject.id, eventObject.id,
profile?.empty ?: false, profile?.empty ?: false,
profile?.empty ?: false, profile?.empty ?: false
System.currentTimeMillis()
)) ))
} }

View File

@ -94,8 +94,7 @@ class IdziennikWebGetMessage(override val data: DataIdziennik,
Metadata.TYPE_MESSAGE, Metadata.TYPE_MESSAGE,
message.id, message.id,
message.seen, message.seen,
message.notified, message.notified
message.addedDate
)) ))
} }

View File

@ -63,6 +63,8 @@ class IdziennikWebGrades(override val data: DataIdziennik,
colorInt = Color.parseColor("#$gradeColor") colorInt = Color.parseColor("#$gradeColor")
} }
val addedDate = grade.getString("Data_wystaw")?.let { Date.fromY_m_d(it).inMillis } ?: System.currentTimeMillis()
val gradeObject = Grade( val gradeObject = Grade(
profileId = profileId, profileId = profileId,
id = id, id = id,
@ -76,7 +78,9 @@ class IdziennikWebGrades(override val data: DataIdziennik,
comment = null, comment = null,
semester = semester, semester = semester,
teacherId = teacher.id, teacherId = teacher.id,
subjectId = subject.id) subjectId = subject.id,
addedDate = addedDate
)
when (grade.getInt("Typ")) { when (grade.getInt("Typ")) {
0 -> { 0 -> {
@ -100,6 +104,8 @@ class IdziennikWebGrades(override val data: DataIdziennik,
colorInt = Color.parseColor("#$historyColor") colorInt = Color.parseColor("#$historyColor")
} }
val addedDate = historyItem.getString("Data_wystaw")?.let { Date.fromY_m_d(it).inMillis } ?: System.currentTimeMillis()
val historyObject = Grade( val historyObject = Grade(
profileId = profileId, profileId = profileId,
id = gradeObject.id * -1, id = gradeObject.id * -1,
@ -113,19 +119,18 @@ class IdziennikWebGrades(override val data: DataIdziennik,
comment = null, comment = null,
semester = historyItem.getInt("Semestr") ?: 1, semester = historyItem.getInt("Semestr") ?: 1,
teacherId = teacher.id, teacherId = teacher.id,
subjectId = subject.id) subjectId = subject.id,
addedDate = addedDate
)
historyObject.parentId = gradeObject.id historyObject.parentId = gradeObject.id
val addedDate = historyItem.getString("Data_wystaw")?.let { Date.fromY_m_d(it).inMillis } ?: System.currentTimeMillis()
data.gradeList.add(historyObject) data.gradeList.add(historyObject)
data.metadataList.add(Metadata( data.metadataList.add(Metadata(
profileId, profileId,
Metadata.TYPE_GRADE, Metadata.TYPE_GRADE,
historyObject.id, historyObject.id,
true, true,
true, true
addedDate
)) ))
} }
// update the current grade's value with an average of all historical grades and itself // update the current grade's value with an average of all historical grades and itself
@ -147,8 +152,6 @@ class IdziennikWebGrades(override val data: DataIdziennik,
} }
} }
val addedDate = grade.getString("Data_wystaw")?.let { Date.fromY_m_d(it).inMillis } ?: System.currentTimeMillis()
data.gradeList.add(gradeObject) data.gradeList.add(gradeObject)
data.metadataList.add( data.metadataList.add(
Metadata( Metadata(
@ -156,8 +159,7 @@ class IdziennikWebGrades(override val data: DataIdziennik,
Metadata.TYPE_GRADE, Metadata.TYPE_GRADE,
id, id,
data.profile.empty, data.profile.empty,
data.profile.empty, data.profile.empty
addedDate
)) ))
} }
} }

View File

@ -57,7 +57,7 @@ class IdziennikWebHomework(override val data: DataIdziennik,
val subjectId = data.getSubject(subjectName, null, subjectName).id val subjectId = data.getSubject(subjectName, null, subjectName).id
val teacherName = homework.getString("usr") ?: return@forEach val teacherName = homework.getString("usr") ?: return@forEach
val teacherId = data.getTeacherByLastFirst(teacherName).id val teacherId = data.getTeacherByLastFirst(teacherName).id
val lessonList = data.db.timetableDao().getForDateNow(profileId, eventDate) val lessonList = data.db.timetableDao().getAllForDateNow(profileId, eventDate)
val startTime = lessonList.firstOrNull { it.subjectId == subjectId }?.displayStartTime val startTime = lessonList.firstOrNull { it.subjectId == subjectId }?.displayStartTime
val topic = homework.getString("tytul")?.trim() ?: "" val topic = homework.getString("tytul")?.trim() ?: ""
@ -77,7 +77,8 @@ class IdziennikWebHomework(override val data: DataIdziennik,
type = Event.TYPE_HOMEWORK, type = Event.TYPE_HOMEWORK,
teacherId = teacherId, teacherId = teacherId,
subjectId = subjectId, subjectId = subjectId,
teamId = data.teamClass?.id ?: -1 teamId = data.teamClass?.id ?: -1,
addedDate = addedDate.inMillis
) )
data.eventList.add(eventObject) data.eventList.add(eventObject)
@ -86,8 +87,7 @@ class IdziennikWebHomework(override val data: DataIdziennik,
Metadata.TYPE_HOMEWORK, Metadata.TYPE_HOMEWORK,
eventObject.id, eventObject.id,
seen, seen,
seen, seen
addedDate.inMillis
)) ))
} }

View File

@ -13,9 +13,12 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.IdziennikWeb
import pl.szczodrzynski.edziennik.data.api.models.ApiError import pl.szczodrzynski.edziennik.data.api.models.ApiError
import pl.szczodrzynski.edziennik.data.db.entity.Metadata import pl.szczodrzynski.edziennik.data.db.entity.Metadata
import pl.szczodrzynski.edziennik.data.db.entity.Notice import pl.szczodrzynski.edziennik.data.db.entity.Notice
import pl.szczodrzynski.edziennik.data.db.entity.Notice.* import pl.szczodrzynski.edziennik.data.db.entity.Notice.Companion.TYPE_NEGATIVE
import pl.szczodrzynski.edziennik.data.db.entity.Notice.Companion.TYPE_NEUTRAL
import pl.szczodrzynski.edziennik.data.db.entity.Notice.Companion.TYPE_POSITIVE
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
import pl.szczodrzynski.edziennik.getJsonObject import pl.szczodrzynski.edziennik.getJsonObject
import pl.szczodrzynski.edziennik.getString
import pl.szczodrzynski.edziennik.utils.models.Date import pl.szczodrzynski.edziennik.utils.models.Date
class IdziennikWebNotices(override val data: DataIdziennik, class IdziennikWebNotices(override val data: DataIdziennik,
@ -53,20 +56,24 @@ class IdziennikWebNotices(override val data: DataIdziennik,
} }
val noticeObject = Notice( val noticeObject = Notice(
profileId, profileId = profileId,
noticeId, id = noticeId,
jNotice.get("Tresc").asString, type = nType,
jNotice.get("Semestr").asInt, semester = jNotice.get("Semestr").asInt,
nType, text = jNotice.getString("Tresc") ?: "",
rTeacher.id) category = null,
points = null,
teacherId = rTeacher.id,
addedDate = addedDate.inMillis
)
data.noticeList.add(noticeObject) data.noticeList.add(noticeObject)
data.metadataList.add(Metadata( data.metadataList.add(Metadata(
profileId, profileId,
Metadata.TYPE_NOTICE, Metadata.TYPE_NOTICE,
noticeObject.id, noticeObject.id,
profile?.empty ?: false, profile?.empty ?: false,
profile?.empty ?: false, profile?.empty ?: false
addedDate.inMillis
)) ))
} }

View File

@ -76,6 +76,11 @@ class IdziennikWebProposedGrades(override val data: DataIdziennik,
else -1 else -1
if (semester1Proposed != "") { if (semester1Proposed != "") {
val addedDate = if (data.profile.empty)
data.profile.dateSemester1Start.inMillis
else
System.currentTimeMillis()
val gradeObject = Grade( val gradeObject = Grade(
profileId = profileId, profileId = profileId,
id = semester1Id, id = semester1Id,
@ -89,26 +94,26 @@ class IdziennikWebProposedGrades(override val data: DataIdziennik,
comment = null, comment = null,
semester = 1, semester = 1,
teacherId = -1, teacherId = -1,
subjectId = subjectObject.id subjectId = subjectObject.id,
addedDate = addedDate
) )
val addedDate = if (data.profile.empty)
data.profile.dateSemester1Start.inMillis
else
System.currentTimeMillis()
data.gradeList.add(gradeObject) data.gradeList.add(gradeObject)
data.metadataList.add(Metadata( data.metadataList.add(Metadata(
profileId, profileId,
Metadata.TYPE_GRADE, Metadata.TYPE_GRADE,
gradeObject.id, gradeObject.id,
profile.empty, profile.empty,
profile.empty, profile.empty
addedDate
)) ))
} }
if (semester2Proposed != "") { if (semester2Proposed != "") {
val addedDate = if (data.profile.empty)
data.profile.dateSemester2Start.inMillis
else
System.currentTimeMillis()
val gradeObject = Grade( val gradeObject = Grade(
profileId = profileId, profileId = profileId,
id = semester2Id, id = semester2Id,
@ -122,22 +127,17 @@ class IdziennikWebProposedGrades(override val data: DataIdziennik,
comment = null, comment = null,
semester = 2, semester = 2,
teacherId = -1, teacherId = -1,
subjectId = subjectObject.id subjectId = subjectObject.id,
addedDate = addedDate
) )
val addedDate = if (data.profile.empty)
data.profile.dateSemester2Start.inMillis
else
System.currentTimeMillis()
data.gradeList.add(gradeObject) data.gradeList.add(gradeObject)
data.metadataList.add(Metadata( data.metadataList.add(Metadata(
profileId, profileId,
Metadata.TYPE_GRADE, Metadata.TYPE_GRADE,
gradeObject.id, gradeObject.id,
profile.empty, profile.empty,
profile.empty, profile.empty
addedDate
)) ))
} }
} }

View File

@ -59,7 +59,7 @@ class IdziennikWebSendMessage(override val data: DataIdziennik,
IdziennikApiMessagesSent(data, null) { IdziennikApiMessagesSent(data, null) {
val message = data.messageList.firstOrNull { it.type == Message.TYPE_SENT && it.subject == subject } val message = data.messageList.firstOrNull { it.type == Message.TYPE_SENT && it.subject == subject }
val metadata = data.metadataList.firstOrNull { it.thingType == Metadata.TYPE_MESSAGE && it.thingId == message?.id } val metadata = data.metadataList.firstOrNull { it.thingType == Metadata.TYPE_MESSAGE && it.thingId == message?.id }
val event = MessageSentEvent(data.profileId, message, metadata?.addedDate) val event = MessageSentEvent(data.profileId, message, message?.addedDate)
EventBus.getDefault().postSticky(event) EventBus.getDefault().postSticky(event)
onSuccess() onSuccess()

View File

@ -165,8 +165,7 @@ class IdziennikWebTimetable(override val data: DataIdziennik,
Metadata.TYPE_LESSON_CHANGE, Metadata.TYPE_LESSON_CHANGE,
lessonObject.id, lessonObject.id,
seen, seen,
seen, seen
System.currentTimeMillis()
)) ))
} }
} }

View File

@ -74,9 +74,9 @@ class IdziennikLoginWeb(val data: DataIdziennik, val onSuccess: () -> Unit) {
Regexes.IDZIENNIK_WEB_LUCKY_NUMBER.find(text)?.also { Regexes.IDZIENNIK_WEB_LUCKY_NUMBER.find(text)?.also {
val number = it[1].toIntOrNull() ?: return@also val number = it[1].toIntOrNull() ?: return@also
val luckyNumberObject = LuckyNumber( val luckyNumberObject = LuckyNumber(
data.profileId, profileId = data.profileId,
Date.getToday(), date = Date.getToday(),
number number = number
) )
data.luckyNumberList.add(luckyNumberObject) data.luckyNumberList.add(luckyNumberObject)
@ -86,8 +86,7 @@ class IdziennikLoginWeb(val data: DataIdziennik, val onSuccess: () -> Unit) {
Metadata.TYPE_LUCKY_NUMBER, Metadata.TYPE_LUCKY_NUMBER,
luckyNumberObject.date.value.toLong(), luckyNumberObject.date.value.toLong(),
true, true,
profile.empty, profile.empty
System.currentTimeMillis()
)) ))
} }
} }

View File

@ -37,8 +37,7 @@ class LibrusApiAnnouncementMarkAsRead(override val data: DataLibrus,
Metadata.TYPE_ANNOUNCEMENT, Metadata.TYPE_ANNOUNCEMENT,
announcement.id, announcement.id,
announcement.seen, announcement.seen,
announcement.notified, announcement.notified
announcement.addedDate
)) ))
onSuccess() onSuccess()
} }

View File

@ -38,15 +38,17 @@ class LibrusApiAnnouncements(override val data: DataLibrus,
val read = announcement.getBoolean("WasRead") ?: false val read = announcement.getBoolean("WasRead") ?: false
val announcementObject = Announcement( val announcementObject = Announcement(
profileId, profileId = profileId,
id, id = id,
subject, subject = subject,
text, text = text,
startDate, startDate = startDate,
endDate, endDate = endDate,
teacherId, teacherId = teacherId,
longId addedDate = addedDate
) ).also {
it.idString = longId
}
data.announcementList.add(announcementObject) data.announcementList.add(announcementObject)
data.setSeenMetadataList.add(Metadata( data.setSeenMetadataList.add(Metadata(
@ -54,8 +56,7 @@ class LibrusApiAnnouncements(override val data: DataLibrus,
Metadata.TYPE_ANNOUNCEMENT, Metadata.TYPE_ANNOUNCEMENT,
id, id,
read, read,
profile.empty || read, profile.empty || read
addedDate
)) ))
} }

View File

@ -26,25 +26,39 @@ class LibrusApiAttendanceTypes(override val data: DataLibrus,
attendanceTypes?.forEach { attendanceType -> attendanceTypes?.forEach { attendanceType ->
val id = attendanceType.getLong("Id") ?: return@forEach val id = attendanceType.getLong("Id") ?: return@forEach
val name = attendanceType.getString("Name") ?: ""
val color = attendanceType.getString("ColorRGB")?.let { Color.parseColor("#$it") } ?: -1
val standardId = when (attendanceType.getBoolean("Standard") ?: false) { val typeName = attendanceType.getString("Name") ?: ""
true -> id val typeSymbol = attendanceType.getString("Short") ?: ""
false -> attendanceType.getJsonObject("StandardType")?.getLong("Id") ?: id val typeColor = attendanceType.getString("ColorRGB")?.let { Color.parseColor("#$it") }
}
val type = when (standardId) { val isStandard = attendanceType.getBoolean("Standard") ?: false
val baseType = when (attendanceType.getJsonObject("StandardType")?.getLong("Id") ?: id) {
1L -> Attendance.TYPE_ABSENT 1L -> Attendance.TYPE_ABSENT
2L -> Attendance.TYPE_BELATED 2L -> Attendance.TYPE_BELATED
3L -> Attendance.TYPE_ABSENT_EXCUSED 3L -> Attendance.TYPE_ABSENT_EXCUSED
4L -> Attendance.TYPE_RELEASED 4L -> Attendance.TYPE_RELEASED
/*100*/else -> Attendance.TYPE_PRESENT /*100*/else -> when (isStandard) {
true -> Attendance.TYPE_PRESENT
false -> Attendance.TYPE_PRESENT_CUSTOM
}
}
val typeShort = when (isStandard) {
true -> data.app.attendanceManager.getTypeShort(baseType)
false -> typeSymbol
} }
data.attendanceTypes.put(id, AttendanceType(profileId, id, name, type, color)) data.attendanceTypes.put(id, AttendanceType(
profileId,
id,
baseType,
typeName,
typeShort,
typeSymbol,
typeColor
))
} }
data.setSyncNext(ENDPOINT_LIBRUS_API_ATTENDANCE_TYPES, 4*DAY) data.setSyncNext(ENDPOINT_LIBRUS_API_ATTENDANCE_TYPES, 2*DAY)
onSuccess(ENDPOINT_LIBRUS_API_ATTENDANCE_TYPES) onSuccess(ENDPOINT_LIBRUS_API_ATTENDANCE_TYPES)
} }
} }

View File

@ -13,7 +13,6 @@ import pl.szczodrzynski.edziennik.data.db.entity.Attendance
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.utils.models.Date import pl.szczodrzynski.edziennik.utils.models.Date
import pl.szczodrzynski.edziennik.utils.models.Time
class LibrusApiAttendances(override val data: DataLibrus, class LibrusApiAttendances(override val data: DataLibrus,
override val lastSync: Long?, override val lastSync: Long?,
@ -42,9 +41,9 @@ class LibrusApiAttendances(override val data: DataLibrus,
val lessonDate = Date.fromY_m_d(attendance.getString("Date")) val lessonDate = Date.fromY_m_d(attendance.getString("Date"))
val teacherId = attendance.getJsonObject("AddedBy")?.getLong("Id") val teacherId = attendance.getJsonObject("AddedBy")?.getLong("Id")
val semester = attendance.getInt("Semester") ?: return@forEach val semester = attendance.getInt("Semester") ?: return@forEach
val type = attendance.getJsonObject("Type")?.getLong("Id") ?: return@forEach
val typeObject = data.attendanceTypes[type] ?: null val typeId = attendance.getJsonObject("Type")?.getLong("Id") ?: return@forEach
val topic = typeObject?.name ?: "" val type = data.attendanceTypes[typeId] ?: null
val startTime = data.lessonRanges.get(lessonNo)?.startTime val startTime = data.lessonRanges.get(lessonNo)?.startTime
@ -52,29 +51,34 @@ class LibrusApiAttendances(override val data: DataLibrus,
data.librusLessons.singleOrNull { it.lessonId == lessonId } data.librusLessons.singleOrNull { it.lessonId == lessonId }
else null else null
val attendanceObject = Attendance(
profileId,
id,
teacherId ?: lesson?.teacherId ?: -1,
lesson?.subjectId ?: -1,
semester,
topic,
lessonDate,
startTime ?: Time(0, 0, 0),
typeObject?.type ?: Attendance.TYPE_CUSTOM
)
val addedDate = Date.fromIso(attendance.getString("AddDate") ?: return@forEach) val addedDate = Date.fromIso(attendance.getString("AddDate") ?: return@forEach)
val attendanceObject = Attendance(
profileId = profileId,
id = id,
baseType = type?.baseType ?: Attendance.TYPE_UNKNOWN,
typeName = type?.typeName ?: "nieznany rodzaj",
typeShort = type?.typeShort ?: "?",
typeSymbol = type?.typeSymbol ?: "?",
typeColor = type?.typeColor,
date = lessonDate,
startTime = startTime,
semester = semester,
teacherId = teacherId ?: lesson?.teacherId ?: -1,
subjectId = lesson?.subjectId ?: -1,
addedDate = addedDate
).also {
it.lessonNumber = lessonNo
}
data.attendanceList.add(attendanceObject) data.attendanceList.add(attendanceObject)
if(typeObject?.type != Attendance.TYPE_PRESENT) { if(type?.baseType != Attendance.TYPE_PRESENT) {
data.metadataList.add(Metadata( data.metadataList.add(Metadata(
profileId, profileId,
Metadata.TYPE_ATTENDANCE, Metadata.TYPE_ATTENDANCE,
id, id,
profile?.empty ?: false, profile?.empty ?: false,
profile?.empty ?: false, profile?.empty ?: false
addedDate
)) ))
} }
} }

View File

@ -55,7 +55,8 @@ class LibrusApiBehaviourGrades(override val data: DataLibrus,
comment = null, comment = null,
semester = 1, semester = 1,
teacherId = -1, teacherId = -1,
subjectId = 1 subjectId = 1,
addedDate = profile.getSemesterStart(1).inMillis
) )
data.gradeList.add(semester1StartGradeObject) data.gradeList.add(semester1StartGradeObject)
@ -64,8 +65,7 @@ class LibrusApiBehaviourGrades(override val data: DataLibrus,
Metadata.TYPE_GRADE, Metadata.TYPE_GRADE,
semester1StartGradeObject.id, semester1StartGradeObject.id,
true, true,
true, true
profile.getSemesterStart(1).inMillis
)) ))
} }
@ -83,7 +83,8 @@ class LibrusApiBehaviourGrades(override val data: DataLibrus,
comment = null, comment = null,
semester = 2, semester = 2,
teacherId = -1, teacherId = -1,
subjectId = 1 subjectId = 1,
addedDate = profile.getSemesterStart(2).inMillis
) )
data.gradeList.add(semester2StartGradeObject) data.gradeList.add(semester2StartGradeObject)
@ -92,8 +93,7 @@ class LibrusApiBehaviourGrades(override val data: DataLibrus,
Metadata.TYPE_GRADE, Metadata.TYPE_GRADE,
semester2StartGradeObject.id, semester2StartGradeObject.id,
true, true,
true, true
profile.getSemesterStart(2).inMillis
)) ))
} }
@ -155,7 +155,8 @@ class LibrusApiBehaviourGrades(override val data: DataLibrus,
comment = if (text != null) description.join(" - ") else null, comment = if (text != null) description.join(" - ") else null,
semester = semester, semester = semester,
teacherId = teacherId, teacherId = teacherId,
subjectId = 1 subjectId = 1,
addedDate = addedDate
).apply { ).apply {
valueMax = valueTo valueMax = valueTo
} }
@ -166,8 +167,7 @@ class LibrusApiBehaviourGrades(override val data: DataLibrus,
Metadata.TYPE_GRADE, Metadata.TYPE_GRADE,
id, id,
profile.empty, profile.empty,
profile.empty, profile.empty
addedDate
)) ))
} }

View File

@ -65,7 +65,8 @@ class LibrusApiDescriptiveGrades(override val data: DataLibrus,
comment = null, comment = null,
semester = semester, semester = semester,
teacherId = teacherId, teacherId = teacherId,
subjectId = subjectId subjectId = subjectId,
addedDate = addedDate
) )
data.gradeList.add(gradeObject) data.gradeList.add(gradeObject)
@ -74,8 +75,7 @@ class LibrusApiDescriptiveGrades(override val data: DataLibrus,
Metadata.TYPE_GRADE, Metadata.TYPE_GRADE,
id, id,
profile.empty, profile.empty,
profile.empty, profile.empty
addedDate
)) ))
} }

View File

@ -56,7 +56,8 @@ class LibrusApiEvents(override val data: DataLibrus,
type = type, type = type,
teacherId = teacherId, teacherId = teacherId,
subjectId = subjectId, subjectId = subjectId,
teamId = teamId teamId = teamId,
addedDate = addedDate
) )
data.eventList.add(eventObject) data.eventList.add(eventObject)
@ -66,8 +67,7 @@ class LibrusApiEvents(override val data: DataLibrus,
Metadata.TYPE_EVENT, Metadata.TYPE_EVENT,
id, id,
profile?.empty ?: false, profile?.empty ?: false,
profile?.empty ?: false, profile?.empty ?: false
addedDate
)) ))
} }

View File

@ -79,7 +79,8 @@ class LibrusApiGrades(override val data: DataLibrus,
comment = null, comment = null,
semester = semester, semester = semester,
teacherId = teacherId, teacherId = teacherId,
subjectId = subjectId subjectId = subjectId,
addedDate = addedDate
) )
grade.getJsonObject("Improvement")?.also { grade.getJsonObject("Improvement")?.also {
@ -98,8 +99,7 @@ class LibrusApiGrades(override val data: DataLibrus,
Metadata.TYPE_GRADE, Metadata.TYPE_GRADE,
id, id,
profile.empty, profile.empty,
profile.empty, profile.empty
addedDate
)) ))
} }

View File

@ -43,7 +43,8 @@ class LibrusApiHomework(override val data: DataLibrus,
type = -1, type = -1,
teacherId = teacherId, teacherId = teacherId,
subjectId = -1, subjectId = -1,
teamId = -1 teamId = -1,
addedDate = addedDate.inMillis
) )
data.eventList.add(eventObject) data.eventList.add(eventObject)
@ -52,8 +53,7 @@ class LibrusApiHomework(override val data: DataLibrus,
Metadata.TYPE_HOMEWORK, Metadata.TYPE_HOMEWORK,
id, id,
profile?.empty ?: false, profile?.empty ?: false,
profile?.empty ?: false, profile?.empty ?: false
addedDate.inMillis
)) ))
} }

View File

@ -33,9 +33,9 @@ class LibrusApiLuckyNumber(override val data: DataLibrus,
val luckyNumberDate = Date.fromY_m_d(luckyNumberEl.getString("LuckyNumberDay")) ?: Date.getToday() val luckyNumberDate = Date.fromY_m_d(luckyNumberEl.getString("LuckyNumberDay")) ?: Date.getToday()
val luckyNumber = luckyNumberEl.getInt("LuckyNumber") ?: -1 val luckyNumber = luckyNumberEl.getInt("LuckyNumber") ?: -1
val luckyNumberObject = LuckyNumber( val luckyNumberObject = LuckyNumber(
profileId, profileId = profileId,
luckyNumberDate, date = luckyNumberDate,
luckyNumber number = luckyNumber
) )
if (luckyNumberDate >= Date.getToday()) if (luckyNumberDate >= Date.getToday())
@ -50,8 +50,7 @@ class LibrusApiLuckyNumber(override val data: DataLibrus,
Metadata.TYPE_LUCKY_NUMBER, Metadata.TYPE_LUCKY_NUMBER,
luckyNumberObject.date.value.toLong(), luckyNumberObject.date.value.toLong(),
true, true,
profile?.empty ?: false, profile?.empty ?: false
System.currentTimeMillis()
)) ))
} }
} }

View File

@ -46,12 +46,15 @@ class LibrusApiNotices(override val data: DataLibrus,
val semester = profile?.dateToSemester(addedDate) ?: 1 val semester = profile?.dateToSemester(addedDate) ?: 1
val noticeObject = Notice( val noticeObject = Notice(
profileId, profileId = profileId,
id, id = id,
categoryText + "\n" + text, type = type,
semester, semester = semester,
type, text = text,
teacherId category = categoryText,
points = null,
teacherId = teacherId,
addedDate = addedDate.inMillis
) )
data.noticeList.add(noticeObject) data.noticeList.add(noticeObject)
@ -61,8 +64,7 @@ class LibrusApiNotices(override val data: DataLibrus,
Metadata.TYPE_NOTICE, Metadata.TYPE_NOTICE,
id, id,
profile?.empty ?: false, profile?.empty ?: false,
profile?.empty ?: false, profile?.empty ?: false
addedDate.inMillis
)) ))
} }

View File

@ -56,7 +56,8 @@ class LibrusApiPointGrades(override val data: DataLibrus,
comment = null, comment = null,
semester = semester, semester = semester,
teacherId = teacherId, teacherId = teacherId,
subjectId = subjectId subjectId = subjectId,
addedDate = addedDate
).apply { ).apply {
valueMax = category?.valueTo ?: 0f valueMax = category?.valueTo ?: 0f
} }
@ -67,8 +68,7 @@ class LibrusApiPointGrades(override val data: DataLibrus,
Metadata.TYPE_GRADE, Metadata.TYPE_GRADE,
id, id,
profile.empty, profile.empty,
profile.empty, profile.empty
addedDate
)) ))
} }

View File

@ -58,8 +58,7 @@ class LibrusApiPtMeetings(override val data: DataLibrus,
Metadata.TYPE_EVENT, Metadata.TYPE_EVENT,
id, id,
profile?.empty ?: false, profile?.empty ?: false,
profile?.empty ?: false, profile?.empty ?: false
System.currentTimeMillis()
)) ))
} }

View File

@ -43,15 +43,15 @@ class LibrusApiTeacherFreeDays(override val data: DataLibrus,
val timeTo = teacherAbsence.getString("TimeTo")?.let { Time.fromH_m_s(it) } val timeTo = teacherAbsence.getString("TimeTo")?.let { Time.fromH_m_s(it) }
val teacherAbsenceObject = TeacherAbsence( val teacherAbsenceObject = TeacherAbsence(
profileId, profileId = profileId,
id, id = id,
teacherId, type = type,
type, name = name,
name, dateFrom = dateFrom,
dateFrom, dateTo = dateTo,
dateTo, timeFrom = timeFrom,
timeFrom, timeTo = timeTo,
timeTo teacherId = teacherId
) )
data.teacherAbsenceList.add(teacherAbsenceObject) data.teacherAbsenceList.add(teacherAbsenceObject)
@ -60,8 +60,7 @@ class LibrusApiTeacherFreeDays(override val data: DataLibrus,
Metadata.TYPE_TEACHER_ABSENCE, Metadata.TYPE_TEACHER_ABSENCE,
id, id,
true, true,
profile?.empty ?: false, profile?.empty ?: false
System.currentTimeMillis()
)) ))
} }

View File

@ -60,7 +60,8 @@ class LibrusApiTextGrades(override val data: DataLibrus,
comment = grade.getString("Phrase") /* whatever it is */, comment = grade.getString("Phrase") /* whatever it is */,
semester = semester, semester = semester,
teacherId = teacherId, teacherId = teacherId,
subjectId = subjectId subjectId = subjectId,
addedDate = addedDate
) )
data.gradeList.add(gradeObject) data.gradeList.add(gradeObject)
@ -69,8 +70,7 @@ class LibrusApiTextGrades(override val data: DataLibrus,
Metadata.TYPE_GRADE, Metadata.TYPE_GRADE,
id, id,
profile.empty, profile.empty,
profile.empty, profile.empty
addedDate
)) ))
} }

View File

@ -198,8 +198,7 @@ class LibrusApiTimetables(override val data: DataLibrus,
Metadata.TYPE_LESSON_CHANGE, Metadata.TYPE_LESSON_CHANGE,
lessonObject.id, lessonObject.id,
seen, seen,
seen, seen
System.currentTimeMillis()
)) ))
} }
data.lessonList.add(lessonObject) data.lessonList.add(lessonObject)

View File

@ -97,7 +97,8 @@ class LibrusMessagesGetList(override val data: DataLibrus,
type = type, type = type,
subject = subject, subject = subject,
body = null, body = null,
senderId = senderId senderId = senderId,
addedDate = sentDate
) )
val messageRecipientObject = MessageRecipient( val messageRecipientObject = MessageRecipient(
@ -120,8 +121,7 @@ class LibrusMessagesGetList(override val data: DataLibrus,
Metadata.TYPE_MESSAGE, Metadata.TYPE_MESSAGE,
id, id,
notified, notified,
notified, notified
sentDate
)) ))
} }

View File

@ -150,8 +150,7 @@ class LibrusMessagesGetMessage(override val data: DataLibrus,
Metadata.TYPE_MESSAGE, Metadata.TYPE_MESSAGE,
messageObject.id, messageObject.id,
true, true,
true, true
messageObject.addedDate
)) ))
} }

View File

@ -50,7 +50,7 @@ class LibrusMessagesSendMessage(override val data: DataLibrus,
LibrusMessagesGetList(data, type = Message.TYPE_SENT, lastSync = null) { LibrusMessagesGetList(data, type = Message.TYPE_SENT, lastSync = null) {
val message = data.messageList.firstOrNull { it.type == Message.TYPE_SENT && it.id == id } val message = data.messageList.firstOrNull { it.type == Message.TYPE_SENT && it.id == id }
val metadata = data.metadataList.firstOrNull { it.thingType == Metadata.TYPE_MESSAGE && it.thingId == message?.id } val metadata = data.metadataList.firstOrNull { it.thingType == Metadata.TYPE_MESSAGE && it.thingId == message?.id }
val event = MessageSentEvent(data.profileId, message, metadata?.addedDate) val event = MessageSentEvent(data.profileId, message, message?.addedDate)
EventBus.getDefault().postSticky(event) EventBus.getDefault().postSticky(event)
onSuccess() onSuccess()

View File

@ -58,7 +58,7 @@ class LibrusSynergiaHomework(override val data: DataLibrus,
elements[9].select("input").attr("onclick") elements[9].select("input").attr("onclick")
)?.get(1)?.toLong() ?: return@forEachIndexed )?.get(1)?.toLong() ?: return@forEachIndexed
val lessons = data.db.timetableDao().getForDateNow(profileId, eventDate) val lessons = data.db.timetableDao().getAllForDateNow(profileId, eventDate)
val startTime = lessons.firstOrNull { it.subjectId == subjectId }?.startTime val startTime = lessons.firstOrNull { it.subjectId == subjectId }?.startTime
val seen = when (profile.empty) { val seen = when (profile.empty) {
@ -76,7 +76,8 @@ class LibrusSynergiaHomework(override val data: DataLibrus,
type = Event.TYPE_HOMEWORK, type = Event.TYPE_HOMEWORK,
teacherId = teacherId, teacherId = teacherId,
subjectId = subjectId, subjectId = subjectId,
teamId = data.teamClass?.id ?: -1 teamId = data.teamClass?.id ?: -1,
addedDate = addedDate.inMillis
) )
data.eventList.add(eventObject) data.eventList.add(eventObject)
@ -85,8 +86,7 @@ class LibrusSynergiaHomework(override val data: DataLibrus,
Metadata.TYPE_HOMEWORK, Metadata.TYPE_HOMEWORK,
id, id,
seen, seen,
seen, seen
addedDate.inMillis
)) ))
} }
} }

View File

@ -6,7 +6,10 @@ package pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.data.api
import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.DataMobidziennik import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.DataMobidziennik
import pl.szczodrzynski.edziennik.data.db.entity.Attendance import pl.szczodrzynski.edziennik.data.db.entity.Attendance
import pl.szczodrzynski.edziennik.data.db.entity.Attendance.* import pl.szczodrzynski.edziennik.data.db.entity.Attendance.Companion.TYPE_ABSENT
import pl.szczodrzynski.edziennik.data.db.entity.Attendance.Companion.TYPE_ABSENT_EXCUSED
import pl.szczodrzynski.edziennik.data.db.entity.Attendance.Companion.TYPE_PRESENT
import pl.szczodrzynski.edziennik.data.db.entity.Attendance.Companion.TYPE_RELEASED
import pl.szczodrzynski.edziennik.data.db.entity.Metadata import pl.szczodrzynski.edziennik.data.db.entity.Metadata
class MobidziennikApiAttendance(val data: DataMobidziennik, rows: List<String>) { class MobidziennikApiAttendance(val data: DataMobidziennik, rows: List<String>) {
@ -23,7 +26,7 @@ class MobidziennikApiAttendance(val data: DataMobidziennik, rows: List<String>)
val id = cols[0].toLong() val id = cols[0].toLong()
val lessonId = cols[1].toLong() val lessonId = cols[1].toLong()
data.mobiLessons.singleOrNull { it.id == lessonId }?.let { lesson -> data.mobiLessons.singleOrNull { it.id == lessonId }?.let { lesson ->
val type = when (cols[4]) { val baseType = when (cols[4]) {
"2" -> TYPE_ABSENT "2" -> TYPE_ABSENT
"5" -> TYPE_ABSENT_EXCUSED "5" -> TYPE_ABSENT_EXCUSED
"4" -> TYPE_RELEASED "4" -> TYPE_RELEASED
@ -31,16 +34,37 @@ class MobidziennikApiAttendance(val data: DataMobidziennik, rows: List<String>)
} }
val semester = data.profile?.dateToSemester(lesson.date) ?: 1 val semester = data.profile?.dateToSemester(lesson.date) ?: 1
val typeName = when (baseType) {
TYPE_ABSENT -> "nieobecność"
TYPE_ABSENT_EXCUSED -> "nieobecność usprawiedliwiona"
TYPE_RELEASED -> "zwolnienie"
TYPE_PRESENT -> "obecność"
else -> "nieznany rodzaj"
}
val typeSymbol = when (baseType) {
TYPE_ABSENT -> "|"
TYPE_ABSENT_EXCUSED -> "+"
TYPE_RELEASED -> "z"
TYPE_PRESENT -> "."
else -> "?"
}
val attendanceObject = Attendance( val attendanceObject = Attendance(
data.profileId, profileId = data.profileId,
id, id = id,
lesson.teacherId, baseType = baseType,
lesson.subjectId, typeName = typeName,
semester, typeShort = data.app.attendanceManager.getTypeShort(baseType),
lesson.topic, typeSymbol = typeSymbol,
lesson.date, typeColor = null,
lesson.startTime, date = lesson.date,
type) startTime = lesson.startTime,
semester = semester,
teacherId = lesson.teacherId,
subjectId = lesson.subjectId
).also {
it.lessonTopic = lesson.topic
}
data.attendanceList.add(attendanceObject) data.attendanceList.add(attendanceObject)
data.metadataList.add( data.metadataList.add(
@ -49,8 +73,7 @@ class MobidziennikApiAttendance(val data: DataMobidziennik, rows: List<String>)
Metadata.TYPE_ATTENDANCE, Metadata.TYPE_ATTENDANCE,
id, id,
data.profile?.empty ?: false, data.profile?.empty ?: false,
data.profile?.empty ?: false, data.profile?.empty ?: false
System.currentTimeMillis()
)) ))
} }
} }

View File

@ -60,7 +60,9 @@ class MobidziennikApiEvents(val data: DataMobidziennik, rows: List<String>) {
type = type, type = type,
teacherId = teacherId, teacherId = teacherId,
subjectId = subjectId, subjectId = subjectId,
teamId = teamId) teamId = teamId,
addedDate = addedDate
)
data.eventList.add(eventObject) data.eventList.add(eventObject)
data.metadataList.add( data.metadataList.add(
@ -69,8 +71,7 @@ class MobidziennikApiEvents(val data: DataMobidziennik, rows: List<String>) {
Metadata.TYPE_EVENT, Metadata.TYPE_EVENT,
id, id,
data.profile?.empty ?: false, data.profile?.empty ?: false,
data.profile?.empty ?: false, data.profile?.empty ?: false
addedDate
)) ))
} }
} }

View File

@ -79,7 +79,9 @@ class MobidziennikApiGrades(val data: DataMobidziennik, rows: List<String>) {
comment = null, comment = null,
semester = semester, semester = semester,
teacherId = teacherId, teacherId = teacherId,
subjectId = subjectId) subjectId = subjectId,
addedDate = addedDate
)
if (data.profile?.empty == true) { if (data.profile?.empty == true) {
addedDate = data.profile.dateSemester1Start.inMillis addedDate = data.profile.dateSemester1Start.inMillis
@ -92,8 +94,7 @@ class MobidziennikApiGrades(val data: DataMobidziennik, rows: List<String>) {
Metadata.TYPE_GRADE, Metadata.TYPE_GRADE,
id, id,
data.profile?.empty ?: false, data.profile?.empty ?: false,
data.profile?.empty ?: false, data.profile?.empty ?: false
addedDate
)) ))
addedDate++ addedDate++
} }

View File

@ -40,7 +40,8 @@ class MobidziennikApiHomework(val data: DataMobidziennik, rows: List<String>) {
type = Event.TYPE_HOMEWORK, type = Event.TYPE_HOMEWORK,
teacherId = teacherId, teacherId = teacherId,
subjectId = subjectId, subjectId = subjectId,
teamId = teamId) teamId = teamId
)
data.eventList.add(eventObject) data.eventList.add(eventObject)
data.metadataList.add( data.metadataList.add(
@ -49,8 +50,7 @@ class MobidziennikApiHomework(val data: DataMobidziennik, rows: List<String>) {
Metadata.TYPE_HOMEWORK, Metadata.TYPE_HOMEWORK,
id, id,
data.profile?.empty ?: false, data.profile?.empty ?: false,
data.profile?.empty ?: false, data.profile?.empty ?: false
System.currentTimeMillis()
)) ))
} }
} }

View File

@ -33,12 +33,16 @@ class MobidziennikApiNotices(val data: DataMobidziennik, rows: List<String>) {
val addedDate = Date.fromYmd(cols[7]).inMillis val addedDate = Date.fromYmd(cols[7]).inMillis
val noticeObject = Notice( val noticeObject = Notice(
data.profileId, profileId = data.profileId,
id, id = id,
text, type = type,
semester, semester = semester,
type, text = text,
teacherId) category = null,
points = null,
teacherId = teacherId,
addedDate = addedDate
)
data.noticeList.add(noticeObject) data.noticeList.add(noticeObject)
data.metadataList.add( data.metadataList.add(
@ -47,8 +51,7 @@ class MobidziennikApiNotices(val data: DataMobidziennik, rows: List<String>) {
Metadata.TYPE_NOTICE, Metadata.TYPE_NOTICE,
id, id,
data.profile?.empty ?: false, data.profile?.empty ?: false,
data.profile?.empty ?: false, data.profile?.empty ?: false
addedDate
)) ))
} }
}} }}

View File

@ -8,9 +8,9 @@ import android.util.SparseArray
import androidx.core.util.set import androidx.core.util.set
import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.DataMobidziennik import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.DataMobidziennik
import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
import pl.szczodrzynski.edziennik.data.db.entity.Lesson
import pl.szczodrzynski.edziennik.data.db.entity.LessonRange import pl.szczodrzynski.edziennik.data.db.entity.LessonRange
import pl.szczodrzynski.edziennik.data.db.entity.Metadata import pl.szczodrzynski.edziennik.data.db.entity.Metadata
import pl.szczodrzynski.edziennik.data.db.entity.Lesson
import pl.szczodrzynski.edziennik.fixName import pl.szczodrzynski.edziennik.fixName
import pl.szczodrzynski.edziennik.keys import pl.szczodrzynski.edziennik.keys
import pl.szczodrzynski.edziennik.singleOrNull import pl.szczodrzynski.edziennik.singleOrNull
@ -97,8 +97,7 @@ class MobidziennikApiTimetable(val data: DataMobidziennik, rows: List<String>) {
Metadata.TYPE_LESSON_CHANGE, Metadata.TYPE_LESSON_CHANGE,
it.id, it.id,
seen, seen,
seen, seen
System.currentTimeMillis()
)) ))
} }
data.lessonList += it data.lessonList += it

View File

@ -17,9 +17,9 @@ class MobidziennikLuckyNumberExtractor(val data: DataMobidziennik, text: String)
val luckyNumber = it.groupValues[1].toInt() val luckyNumber = it.groupValues[1].toInt()
val luckyNumberObject = LuckyNumber( val luckyNumberObject = LuckyNumber(
data.profileId, profileId = data.profileId,
Date.getToday(), date = Date.getToday(),
luckyNumber number = luckyNumber
) )
data.luckyNumberList.add(luckyNumberObject) data.luckyNumberList.add(luckyNumberObject)
@ -29,8 +29,7 @@ class MobidziennikLuckyNumberExtractor(val data: DataMobidziennik, text: String)
Metadata.TYPE_LUCKY_NUMBER, Metadata.TYPE_LUCKY_NUMBER,
luckyNumberObject.date.value.toLong(), luckyNumberObject.date.value.toLong(),
true, true,
data.profile?.empty ?: false, data.profile?.empty ?: false
System.currentTimeMillis()
)) ))
} catch (_: Exception){} } catch (_: Exception){}
} }

View File

@ -11,7 +11,12 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.ENDPOINT_MOBID
import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.data.MobidziennikWeb import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.data.MobidziennikWeb
import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
import pl.szczodrzynski.edziennik.data.db.entity.Attendance import pl.szczodrzynski.edziennik.data.db.entity.Attendance
import pl.szczodrzynski.edziennik.data.db.entity.Attendance.* import pl.szczodrzynski.edziennik.data.db.entity.Attendance.Companion.TYPE_ABSENT
import pl.szczodrzynski.edziennik.data.db.entity.Attendance.Companion.TYPE_ABSENT_EXCUSED
import pl.szczodrzynski.edziennik.data.db.entity.Attendance.Companion.TYPE_BELATED
import pl.szczodrzynski.edziennik.data.db.entity.Attendance.Companion.TYPE_PRESENT
import pl.szczodrzynski.edziennik.data.db.entity.Attendance.Companion.TYPE_RELEASED
import pl.szczodrzynski.edziennik.data.db.entity.Attendance.Companion.TYPE_UNKNOWN
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.fixName import pl.szczodrzynski.edziennik.fixName
@ -71,6 +76,18 @@ class MobidziennikWebAttendance(override val data: DataMobidziennik,
val start = System.currentTimeMillis() val start = System.currentTimeMillis()
val types = Regexes.MOBIDZIENNIK_ATTENDANCE_TYPES
.find(text)
?.get(1)
?.split("<br/>")
?.map {
it.trimEnd(',')
.split(" ", limit = 2)
.let { it.getOrNull(0) to it.getOrNull(1) }
}
?.toMap()
val typeSymbols = types?.keys?.filterNotNull() ?: listOf()
Regexes.MOBIDZIENNIK_ATTENDANCE_TABLE.findAll(text).forEach { tableResult -> Regexes.MOBIDZIENNIK_ATTENDANCE_TABLE.findAll(text).forEach { tableResult ->
val table = tableResult[1] val table = tableResult[1]
val lessonDates = mutableListOf<Date>() val lessonDates = mutableListOf<Date>()
@ -92,14 +109,14 @@ class MobidziennikWebAttendance(override val data: DataMobidziennik,
return@forEach return@forEach
ranges.forEach { range -> ranges.forEach { range ->
val lessonDate = dateIterator.next() val lessonDate = dateIterator.next()
val entry = entriesIterator.next() var entry = entriesIterator.next()
if (entry.isBlank()) if (entry.isBlank())
return@forEach return@forEach
val startTime = Time.fromH_m(range[1]) val startTime = Time.fromH_m(range[1])
val entryIterator = entry.iterator()
range[2].split(" / ").mapNotNull { Regexes.MOBIDZIENNIK_ATTENDANCE_LESSON.find(it) }.forEachIndexed { index, lesson -> range[2].split(" / ").mapNotNull { Regexes.MOBIDZIENNIK_ATTENDANCE_LESSON.find(it) }.forEachIndexed { index, lesson ->
val topic = lesson[2] val topic = lesson[2]
if (topic.startsWith("Lekcja odwołana: ") || !entryIterator.hasNext()) if (topic.startsWith("Lekcja odwołana: ") || entry.isEmpty())
return@forEachIndexed return@forEachIndexed
val subjectName = lesson[1] val subjectName = lesson[1]
//val team = lesson[3] //val team = lesson[3]
@ -108,39 +125,58 @@ class MobidziennikWebAttendance(override val data: DataMobidziennik,
val teacherId = data.teacherList.singleOrNull { it.fullNameLastFirst == teacherName }?.id ?: -1 val teacherId = data.teacherList.singleOrNull { it.fullNameLastFirst == teacherName }?.id ?: -1
val subjectId = data.subjectList.singleOrNull { it.longName == subjectName }?.id ?: -1 val subjectId = data.subjectList.singleOrNull { it.longName == subjectName }?.id ?: -1
val type = when (entryIterator.nextChar()) { var typeSymbol = ""
'.' -> TYPE_PRESENT for (symbol in typeSymbols) {
'|' -> TYPE_ABSENT if (entry.startsWith(symbol) && symbol.length > typeSymbol.length)
'+' -> TYPE_ABSENT_EXCUSED typeSymbol = symbol
's' -> TYPE_BELATED
'z' -> TYPE_RELEASED
else -> TYPE_PRESENT
} }
entry = entry.removePrefix(typeSymbol)
val baseType = when (typeSymbol) {
"." -> TYPE_PRESENT
"|" -> TYPE_ABSENT
"+" -> TYPE_ABSENT_EXCUSED
"s" -> TYPE_BELATED
"z" -> TYPE_RELEASED
else -> TYPE_UNKNOWN
}
val typeName = types?.get(typeSymbol) ?: ""
val typeShort = when (baseType) {
TYPE_UNKNOWN -> typeSymbol
else -> data.app.attendanceManager.getTypeShort(baseType)
}
val semester = data.profile?.dateToSemester(lessonDate) ?: 1 val semester = data.profile?.dateToSemester(lessonDate) ?: 1
val id = lessonDate.combineWith(startTime) / 6L * 10L + (lesson[0].hashCode() and 0xFFFF) + index val id = lessonDate.combineWith(startTime) / 6L * 10L + (lesson[0].hashCode() and 0xFFFF) + index
val attendanceObject = Attendance( val attendanceObject = Attendance(
data.profileId, profileId = profileId,
id, id = id,
teacherId, baseType = baseType,
subjectId, typeName = typeName,
semester, typeShort = typeShort,
topic, typeSymbol = typeSymbol,
lessonDate, typeColor = null,
startTime, date = lessonDate,
type) startTime = startTime,
semester = semester,
teacherId = teacherId,
subjectId = subjectId
).also {
it.lessonTopic = topic
}
data.attendanceList.add(attendanceObject) data.attendanceList.add(attendanceObject)
if (type != TYPE_PRESENT) { if (baseType != TYPE_PRESENT) {
data.metadataList.add( data.metadataList.add(
Metadata( Metadata(
data.profileId, data.profileId,
Metadata.TYPE_ATTENDANCE, Metadata.TYPE_ATTENDANCE,
id, id,
data.profile?.empty ?: false, data.profile?.empty ?: false,
data.profile?.empty ?: false, data.profile?.empty ?: false
System.currentTimeMillis()
)) ))
} }
} }

View File

@ -89,8 +89,8 @@ class MobidziennikWebCalendar(override val data: DataMobidziennik,
Metadata.TYPE_EVENT, Metadata.TYPE_EVENT,
eventObject.id, eventObject.id,
profile?.empty ?: false, profile?.empty ?: false,
profile?.empty ?: false, profile?.empty ?: false
System.currentTimeMillis() /* no addedDate here though */ /* no addedDate here though */
)) ))
} }
} }

View File

@ -139,8 +139,7 @@ class MobidziennikWebGetMessage(override val data: DataMobidziennik,
Metadata.TYPE_MESSAGE, Metadata.TYPE_MESSAGE,
message.id, message.id,
true, true,
true, true
message.addedDate
)) ))
} }

View File

@ -125,7 +125,8 @@ class MobidziennikWebGrades(override val data: DataMobidziennik,
comment = null, comment = null,
semester = gradeSemester, semester = gradeSemester,
teacherId = teacherId, teacherId = teacherId,
subjectId = subjectId subjectId = subjectId,
addedDate = gradeAddedDateMillis
) )
gradeObject.classAverage = gradeClassAverage gradeObject.classAverage = gradeClassAverage
@ -137,8 +138,7 @@ class MobidziennikWebGrades(override val data: DataMobidziennik,
Metadata.TYPE_GRADE, Metadata.TYPE_GRADE,
gradeObject.id, gradeObject.id,
profile.empty, profile.empty,
profile.empty, profile.empty
gradeAddedDateMillis
)) ))
} }
} }

View File

@ -77,11 +77,12 @@ class MobidziennikWebMessagesAll(override val data: DataMobidziennik,
type = type, type = type,
subject = subject, subject = subject,
body = null, body = null,
senderId = senderId senderId = senderId,
addedDate = addedDate
) )
data.messageList.add(message) data.messageList.add(message)
data.metadataList.add(Metadata(profileId, Metadata.TYPE_MESSAGE, message.id, true, true, addedDate)) data.metadataList.add(Metadata(profileId, Metadata.TYPE_MESSAGE, message.id, true, true))
} }
// sync every 7 days as we probably don't expect more than // sync every 7 days as we probably don't expect more than

View File

@ -63,7 +63,8 @@ class MobidziennikWebMessagesInbox(override val data: DataMobidziennik,
type = Message.TYPE_RECEIVED, type = Message.TYPE_RECEIVED,
subject = subject, subject = subject,
body = null, body = null,
senderId = senderId senderId = senderId,
addedDate = addedDate
) )
if (hasAttachments) if (hasAttachments)
@ -76,8 +77,7 @@ class MobidziennikWebMessagesInbox(override val data: DataMobidziennik,
Metadata.TYPE_MESSAGE, Metadata.TYPE_MESSAGE,
message.id, message.id,
isRead, isRead,
isRead || profile?.empty ?: false, isRead || profile?.empty ?: false
addedDate
)) ))
} }

View File

@ -78,7 +78,8 @@ class MobidziennikWebMessagesSent(override val data: DataMobidziennik,
type = Message.TYPE_SENT, type = Message.TYPE_SENT,
subject = subject, subject = subject,
body = null, body = null,
senderId = null senderId = null,
addedDate = addedDate
) )
if (hasAttachments) if (hasAttachments)
@ -91,8 +92,7 @@ class MobidziennikWebMessagesSent(override val data: DataMobidziennik,
Metadata.TYPE_MESSAGE, Metadata.TYPE_MESSAGE,
message.id, message.id,
true, true,
true, true
addedDate
)) ))
} }

View File

@ -45,7 +45,7 @@ class MobidziennikWebSendMessage(override val data: DataMobidziennik,
MobidziennikWebMessagesAll(data, null) { MobidziennikWebMessagesAll(data, null) {
val message = data.messageList.firstOrNull { it.type == Message.TYPE_SENT && it.subject == subject } val message = data.messageList.firstOrNull { it.type == Message.TYPE_SENT && it.subject == subject }
val metadata = data.metadataList.firstOrNull { it.thingType == Metadata.TYPE_MESSAGE && it.thingId == message?.id } val metadata = data.metadataList.firstOrNull { it.thingType == Metadata.TYPE_MESSAGE && it.thingId == message?.id }
val event = MessageSentEvent(data.profileId, message, metadata?.addedDate) val event = MessageSentEvent(data.profileId, message, message?.addedDate)
EventBus.getDefault().postSticky(event) EventBus.getDefault().postSticky(event)
onSuccess() onSuccess()

View File

@ -7,7 +7,7 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.DataVulcan
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.ENDPOINT_VULCAN_API_ATTENDANCE import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.ENDPOINT_VULCAN_API_ATTENDANCE
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.VulcanApi import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.VulcanApi
import pl.szczodrzynski.edziennik.data.db.entity.Attendance import pl.szczodrzynski.edziennik.data.db.entity.Attendance
import pl.szczodrzynski.edziennik.data.db.entity.Attendance.TYPE_PRESENT import pl.szczodrzynski.edziennik.data.db.entity.Attendance.Companion.TYPE_PRESENT
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.utils.models.Date import pl.szczodrzynski.edziennik.utils.models.Date
@ -38,38 +38,43 @@ class VulcanApiAttendance(override val data: DataVulcan,
json.getJsonObject("Data")?.getJsonArray("Frekwencje")?.forEach { attendanceEl -> json.getJsonObject("Data")?.getJsonArray("Frekwencje")?.forEach { attendanceEl ->
val attendance = attendanceEl.asJsonObject val attendance = attendanceEl.asJsonObject
val attendanceCategory = data.attendanceTypes.get(attendance.getLong("IdKategoria") ?: return@forEach) val type = data.attendanceTypes.get(attendance.getLong("IdKategoria") ?: return@forEach)
?: return@forEach ?: return@forEach
val type = attendanceCategory.type
val id = (attendance.getInt("Dzien") ?: 0) + (attendance.getInt("Numer") ?: 0) val id = (attendance.getInt("Dzien") ?: 0) + (attendance.getInt("Numer") ?: 0)
val lessonDateMillis = Date.fromY_m_d(attendance.getString("DzienTekst")).inMillis val lessonDateMillis = Date.fromY_m_d(attendance.getString("DzienTekst")).inMillis
val lessonDate = Date.fromMillis(lessonDateMillis) val lessonDate = Date.fromMillis(lessonDateMillis)
val startTime = data.lessonRanges.get(attendance.getInt("Numer") ?: 0)?.startTime
val lessonSemester = profile.dateToSemester(lessonDate) val lessonSemester = profile.dateToSemester(lessonDate)
val attendanceObject = Attendance( val attendanceObject = Attendance(
profileId, profileId = profileId,
id.toLong(), id = id.toLong(),
-1, baseType = type.baseType,
attendance.getLong("IdPrzedmiot") ?: -1, typeName = type.typeName,
lessonSemester, typeShort = type.typeShort,
attendance.getString("PrzedmiotNazwa") + attendanceCategory.name.let { " - $it" }, typeSymbol = type.typeSymbol,
lessonDate, typeColor = type.typeColor,
data.lessonRanges.get(attendance.getInt("Numer") ?: 0)?.startTime, date = lessonDate,
type) startTime = startTime,
semester = lessonSemester,
teacherId = -1,
subjectId = attendance.getLong("IdPrzedmiot") ?: -1,
addedDate = lessonDate.combineWith(startTime)
).also {
it.lessonNumber = attendance.getInt("Numer")
}
data.attendanceList.add(attendanceObject) data.attendanceList.add(attendanceObject)
if (attendanceObject.type != TYPE_PRESENT) { if (type.baseType != TYPE_PRESENT) {
data.metadataList.add(Metadata( data.metadataList.add(Metadata(
profileId, profileId,
Metadata.TYPE_ATTENDANCE, Metadata.TYPE_ATTENDANCE,
attendanceObject.id, attendanceObject.id,
profile.empty, profile.empty,
profile.empty, profile.empty
attendanceObject.lessonDate.combineWith(attendanceObject.startTime)
)) ))
} }
} }

View File

@ -114,11 +114,11 @@ class VulcanApiDictionaries(override val data: DataVulcan,
private fun saveAttendanceType(attendanceType: JsonObject) { private fun saveAttendanceType(attendanceType: JsonObject) {
val id = attendanceType.getLong("Id") ?: return val id = attendanceType.getLong("Id") ?: return
val name = attendanceType.getString("Nazwa") ?: "" val typeName = attendanceType.getString("Nazwa") ?: ""
val absent = attendanceType.getBoolean("Nieobecnosc") ?: false val absent = attendanceType.getBoolean("Nieobecnosc") ?: false
val excused = attendanceType.getBoolean("Usprawiedliwione") ?: false val excused = attendanceType.getBoolean("Usprawiedliwione") ?: false
val type = if (absent) { val baseType = if (absent) {
if (excused) if (excused)
Attendance.TYPE_ABSENT_EXCUSED Attendance.TYPE_ABSENT_EXCUSED
else else
@ -137,15 +137,35 @@ class VulcanApiDictionaries(override val data: DataVulcan,
else if (present) else if (present)
Attendance.TYPE_PRESENT Attendance.TYPE_PRESENT
else else
Attendance.TYPE_CUSTOM Attendance.TYPE_UNKNOWN
}
val (typeColor, typeSymbol) = when (id.toInt()) {
1 -> 0xffffffff to "" // obecność
2 -> 0xffffa687 to "" // nieobecność
3 -> 0xfffcc150 to "u" // nieobecność usprawiedliwiona
4 -> 0xffede049 to "s" // spóźnienie
5 -> 0xffbbdd5f to "su" // spóźnienie usprawiedliwione
6 -> 0xffa9c9fd to "ns" // nieobecny z przyczyn szkolnych
7 -> 0xffddbbe5 to "z" // zwolniony
8 -> 0xffffffff to "" // usunięty wpis
else -> null to "?"
}
val typeShort = when (id.toInt()) {
6 -> "ns" // nieobecny z przyczyn szkolnych
8 -> "" // usunięty wpis
else -> data.app.attendanceManager.getTypeShort(baseType)
} }
val attendanceTypeObject = AttendanceType( val attendanceTypeObject = AttendanceType(
profileId, profileId,
id, id,
name, baseType,
type, typeName,
-1 typeShort,
typeSymbol,
typeColor?.toInt()
) )
data.attendanceTypes.put(id, attendanceTypeObject) data.attendanceTypes.put(id, attendanceTypeObject)

View File

@ -59,7 +59,7 @@ class VulcanApiEvents(override val data: DataVulcan,
val teacherId = event.getLong("IdPracownik") ?: -1 val teacherId = event.getLong("IdPracownik") ?: -1
val topic = event.getString("Opis")?.trim() ?: "" val topic = event.getString("Opis")?.trim() ?: ""
val lessonList = data.db.timetableDao().getForDateNow(profileId, eventDate) val lessonList = data.db.timetableDao().getAllForDateNow(profileId, eventDate)
val startTime = lessonList.firstOrNull { it.subjectId == subjectId }?.startTime val startTime = lessonList.firstOrNull { it.subjectId == subjectId }?.startTime
val type = when (isHomework) { val type = when (isHomework) {
@ -90,8 +90,7 @@ class VulcanApiEvents(override val data: DataVulcan,
if (isHomework) Metadata.TYPE_HOMEWORK else Metadata.TYPE_EVENT, if (isHomework) Metadata.TYPE_HOMEWORK else Metadata.TYPE_EVENT,
id, id,
profile.empty, profile.empty,
profile.empty, profile.empty
System.currentTimeMillis()
)) ))
} }

View File

@ -101,7 +101,8 @@ class VulcanApiGrades(override val data: DataVulcan,
comment = null, comment = null,
semester = data.studentSemesterNumber, semester = data.studentSemesterNumber,
teacherId = teacherId, teacherId = teacherId,
subjectId = subjectId subjectId = subjectId,
addedDate = addedDate
) )
data.gradeList.add(gradeObject) data.gradeList.add(gradeObject)
@ -110,9 +111,7 @@ class VulcanApiGrades(override val data: DataVulcan,
Metadata.TYPE_GRADE, Metadata.TYPE_GRADE,
id, id,
profile.empty, profile.empty,
profile.empty, profile.empty
addedDate
)) ))
} }

View File

@ -37,8 +37,7 @@ class VulcanApiMessagesChangeStatus(override val data: DataVulcan,
Metadata.TYPE_MESSAGE, Metadata.TYPE_MESSAGE,
messageObject.id, messageObject.id,
true, true,
true, true
messageObject.addedDate
)) ))
messageObject.seen = true messageObject.seen = true

View File

@ -72,7 +72,8 @@ class VulcanApiMessagesInbox(override val data: DataVulcan,
type = TYPE_RECEIVED, type = TYPE_RECEIVED,
subject = subject, subject = subject,
body = body.replace("\n", "<br>"), body = body.replace("\n", "<br>"),
senderId = senderId senderId = senderId,
addedDate = sentDate
) )
val messageRecipientObject = MessageRecipient( val messageRecipientObject = MessageRecipient(
@ -90,8 +91,7 @@ class VulcanApiMessagesInbox(override val data: DataVulcan,
Metadata.TYPE_MESSAGE, Metadata.TYPE_MESSAGE,
id, id,
readDate > 0, readDate > 0,
readDate > 0, readDate > 0
sentDate
)) ))
} }

View File

@ -97,7 +97,8 @@ class VulcanApiMessagesSent(override val data: DataVulcan,
type = TYPE_SENT, type = TYPE_SENT,
subject = subject, subject = subject,
body = body.replace("\n", "<br>"), body = body.replace("\n", "<br>"),
senderId = null senderId = null,
addedDate = sentDate
) )
data.messageList.add(messageObject) data.messageList.add(messageObject)
@ -106,8 +107,7 @@ class VulcanApiMessagesSent(override val data: DataVulcan,
Metadata.TYPE_MESSAGE, Metadata.TYPE_MESSAGE,
id, id,
true, true,
true, true
sentDate
)) ))
} }

View File

@ -16,7 +16,6 @@ import pl.szczodrzynski.edziennik.getJsonArray
import pl.szczodrzynski.edziennik.getLong import pl.szczodrzynski.edziennik.getLong
import pl.szczodrzynski.edziennik.getString import pl.szczodrzynski.edziennik.getString
import pl.szczodrzynski.edziennik.toSparseArray import pl.szczodrzynski.edziennik.toSparseArray
import pl.szczodrzynski.edziennik.utils.models.Date
class VulcanApiNotices(override val data: DataVulcan, class VulcanApiNotices(override val data: DataVulcan,
override val lastSync: Long?, override val lastSync: Long?,
@ -41,15 +40,21 @@ class VulcanApiNotices(override val data: DataVulcan,
val id = notice.getLong("Id") ?: return@forEach val id = notice.getLong("Id") ?: return@forEach
val text = notice.getString("TrescUwagi") ?: return@forEach val text = notice.getString("TrescUwagi") ?: return@forEach
val teacherId = notice.getLong("IdPracownik") ?: -1 val teacherId = notice.getLong("IdPracownik") ?: -1
val addedDate = Date.fromY_m_d(notice.getString("DataWpisuTekst")).inMillis val addedDate = notice.getLong("DataModyfikacji")?.times(1000) ?: System.currentTimeMillis()
val categoryId = notice.getLong("IdKategoriaUwag") ?: -1
val categoryText = data.noticeTypes[categoryId]?.name ?: ""
val noticeObject = Notice( val noticeObject = Notice(
profileId, profileId = profileId,
id, id = id,
text, type = Notice.TYPE_NEUTRAL,
profile.currentSemester, semester = profile.currentSemester,
Notice.TYPE_NEUTRAL, text = text,
teacherId category = categoryText,
points = null,
teacherId = teacherId,
addedDate = addedDate
) )
data.noticeList.add(noticeObject) data.noticeList.add(noticeObject)
@ -58,8 +63,7 @@ class VulcanApiNotices(override val data: DataVulcan,
Metadata.TYPE_NOTICE, Metadata.TYPE_NOTICE,
id, id,
profile.empty, profile.empty,
profile.empty, profile.empty
addedDate
)) ))
} }

View File

@ -82,8 +82,7 @@ class VulcanApiProposedGrades(override val data: DataVulcan,
Metadata.TYPE_GRADE, Metadata.TYPE_GRADE,
gradeObject.id, gradeObject.id,
data.profile?.empty ?: false, data.profile?.empty ?: false,
data.profile?.empty ?: false, data.profile?.empty ?: false
System.currentTimeMillis()
)) ))
} }
} }

View File

@ -54,7 +54,7 @@ class VulcanApiSendMessage(override val data: DataVulcan,
VulcanApiMessagesSent(data, null) { VulcanApiMessagesSent(data, null) {
val message = data.messageList.firstOrNull { it.type == Message.TYPE_SENT && it.subject == subject } val message = data.messageList.firstOrNull { it.type == Message.TYPE_SENT && it.subject == subject }
val metadata = data.metadataList.firstOrNull { it.thingType == Metadata.TYPE_MESSAGE && it.thingId == messageId } val metadata = data.metadataList.firstOrNull { it.thingType == Metadata.TYPE_MESSAGE && it.thingId == messageId }
val event = MessageSentEvent(data.profileId, message, metadata?.addedDate) val event = MessageSentEvent(data.profileId, message, message?.addedDate)
EventBus.getDefault().postSticky(event) EventBus.getDefault().postSticky(event)
onSuccess() onSuccess()

View File

@ -184,8 +184,7 @@ class VulcanApiTimetable(override val data: DataVulcan,
Metadata.TYPE_LESSON_CHANGE, Metadata.TYPE_LESSON_CHANGE,
lessonObject.id, lessonObject.id,
seen, seen,
seen, seen
System.currentTimeMillis()
)) ))
} }

View File

@ -88,6 +88,7 @@ abstract class Data(val app: App, val profile: Profile?, val loginStore: LoginSt
var teacherOnConflictStrategy = OnConflictStrategy.IGNORE var teacherOnConflictStrategy = OnConflictStrategy.IGNORE
var eventListReplace = false var eventListReplace = false
var messageListReplace = false var messageListReplace = false
var announcementListReplace = false
val classrooms = LongSparseArray<Classroom>() val classrooms = LongSparseArray<Classroom>()
val attendanceTypes = LongSparseArray<AttendanceType>() val attendanceTypes = LongSparseArray<AttendanceType>()
@ -120,7 +121,6 @@ abstract class Data(val app: App, val profile: Profile?, val loginStore: LoginSt
val attendanceList = mutableListOf<Attendance>() val attendanceList = mutableListOf<Attendance>()
val announcementList = mutableListOf<Announcement>() val announcementList = mutableListOf<Announcement>()
val announcementIgnoreList = mutableListOf<Announcement>()
val luckyNumberList = mutableListOf<LuckyNumber>() val luckyNumberList = mutableListOf<LuckyNumber>()
@ -178,7 +178,6 @@ abstract class Data(val app: App, val profile: Profile?, val loginStore: LoginSt
noticeList.clear() noticeList.clear()
attendanceList.clear() attendanceList.clear()
announcementList.clear() announcementList.clear()
announcementIgnoreList.clear()
luckyNumberList.clear() luckyNumberList.clear()
teacherAbsenceList.clear() teacherAbsenceList.clear()
messageList.clear() messageList.clear()
@ -284,39 +283,19 @@ abstract class Data(val app: App, val profile: Profile?, val loginStore: LoginSt
d("Metadata saved in ${System.currentTimeMillis()-startTime} ms") d("Metadata saved in ${System.currentTimeMillis()-startTime} ms")
startTime = System.currentTimeMillis() startTime = System.currentTimeMillis()
if (lessonList.isNotEmpty()) { db.timetableDao().putAll(lessonList, removeNotKept = true)
db.timetableDao() += lessonList db.gradeDao().putAll(gradeList, removeNotKept = true)
} db.eventDao().putAll(eventList, forceReplace = eventListReplace, removeNotKept = true)
if (gradeList.isNotEmpty()) {
db.gradeDao().addAll(gradeList)
}
if (eventList.isNotEmpty()) {
if (eventListReplace)
db.eventDao().replaceAll(eventList)
else
db.eventDao().upsertAll(eventList, removeNotKept = true)
}
if (noticeList.isNotEmpty()) { if (noticeList.isNotEmpty()) {
db.noticeDao().clear(profile.id) db.noticeDao().clear(profile.id)
db.noticeDao().addAll(noticeList) db.noticeDao().putAll(noticeList)
} }
if (attendanceList.isNotEmpty()) db.attendanceDao().putAll(attendanceList, removeNotKept = true)
db.attendanceDao().addAll(attendanceList) db.announcementDao().putAll(announcementList, forceReplace = announcementListReplace, removeNotKept = false)
if (announcementList.isNotEmpty()) db.luckyNumberDao().putAll(luckyNumberList)
db.announcementDao().addAll(announcementList) db.teacherAbsenceDao().putAll(teacherAbsenceList)
if (announcementIgnoreList.isNotEmpty())
db.announcementDao().addAllIgnore(announcementIgnoreList)
if (luckyNumberList.isNotEmpty())
db.luckyNumberDao().addAll(luckyNumberList)
if (teacherAbsenceList.isNotEmpty())
db.teacherAbsenceDao().addAll(teacherAbsenceList)
if (messageList.isNotEmpty()) { db.messageDao().putAll(messageList, forceReplace = messageListReplace, removeNotKept = false)
if (messageListReplace)
db.messageDao().replaceAll(messageList)
else
db.messageDao().upsertAll(messageList, removeNotKept = false) // TODO dataRemoveModel for messages
}
if (messageRecipientList.isNotEmpty()) if (messageRecipientList.isNotEmpty())
db.messageRecipientDao().addAll(messageRecipientList) db.messageRecipientDao().addAll(messageRecipientList)
if (messageRecipientIgnoreList.isNotEmpty()) if (messageRecipientIgnoreList.isNotEmpty())
@ -357,7 +336,7 @@ abstract class Data(val app: App, val profile: Profile?, val loginStore: LoginSt
} }
fun shouldSyncLuckyNumber(): Boolean { fun shouldSyncLuckyNumber(): Boolean {
return (db.luckyNumberDao().getNearestFutureNow(profileId, Date.getToday().value) ?: -1) == -1 return db.luckyNumberDao().getNearestFutureNow(profileId, Date.getToday()) == null
} }
/*fun error(tag: String, errorCode: Int, response: Response? = null, throwable: Throwable? = null, apiResponse: JsonObject? = null) { /*fun error(tag: String, errorCode: Int, response: Response? = null, throwable: Throwable? = null, apiResponse: JsonObject? = null) {

View File

@ -20,10 +20,10 @@ open class DataRemoveModel {
fun commit(profileId: Int, dao: TimetableDao) { fun commit(profileId: Int, dao: TimetableDao) {
if (dateFrom != null && dateTo != null) { if (dateFrom != null && dateTo != null) {
dao.clearBetweenDates(profileId, dateFrom, dateTo) dao.dontKeepBetweenDates(profileId, dateFrom, dateTo)
} else { } else {
dateFrom?.let { dateFrom -> dao.clearFromDate(profileId, dateFrom) } dateFrom?.let { dateFrom -> dao.dontKeepFromDate(profileId, dateFrom) }
dateTo?.let { dateTo -> dao.clearToDate(profileId, dateTo) } dateTo?.let { dateTo -> dao.dontKeepToDate(profileId, dateTo) }
} }
} }
} }
@ -69,7 +69,7 @@ open class DataRemoveModel {
fun commit(profileId: Int, dao: AttendanceDao) { fun commit(profileId: Int, dao: AttendanceDao) {
if (dateFrom != null) { if (dateFrom != null) {
dao.clearAfterDate(profileId, dateFrom) dao.dontKeepAfterDate(profileId, dateFrom)
} }
} }
} }

View File

@ -40,8 +40,7 @@ class AppSync(val app: App, val notifications: MutableList<Notification>, val pr
Metadata.TYPE_EVENT, Metadata.TYPE_EVENT,
event.id, event.id,
isPast || markAsSeen || event.seen, isPast || markAsSeen || event.seen,
isPast || markAsSeen || event.notified, isPast || markAsSeen || event.notified
event.addedDate
) )
}) })
return app.db.eventDao().upsertAll(events).size return app.db.eventDao().upsertAll(events).size

View File

@ -53,7 +53,7 @@ class Notifications(val app: App, val notifications: MutableList<Notification>,
profileId = lesson.profileId, profileId = lesson.profileId,
profileName = profiles.singleOrNull { it.id == lesson.profileId }?.name, profileName = profiles.singleOrNull { it.id == lesson.profileId }?.name,
viewId = MainActivity.DRAWER_ITEM_TIMETABLE, viewId = MainActivity.DRAWER_ITEM_TIMETABLE,
addedDate = lesson.addedDate addedDate = System.currentTimeMillis()
).addExtra("timetableDate", lesson.displayDate?.stringY_m_d ?: "") ).addExtra("timetableDate", lesson.displayDate?.stringY_m_d ?: "")
} }
} }
@ -117,7 +117,7 @@ class Notifications(val app: App, val notifications: MutableList<Notification>,
} }
private fun gradeNotifications() { private fun gradeNotifications() {
for (grade in app.db.gradeDao().notNotifiedNow) { for (grade in app.db.gradeDao().getNotNotifiedNow()) {
val gradeName = when (grade.type) { val gradeName = when (grade.type) {
Grade.TYPE_SEMESTER1_PROPOSED, Grade.TYPE_SEMESTER2_PROPOSED -> app.getString(R.string.grade_semester_proposed_format_2, grade.name) Grade.TYPE_SEMESTER1_PROPOSED, Grade.TYPE_SEMESTER2_PROPOSED -> app.getString(R.string.grade_semester_proposed_format_2, grade.name)
Grade.TYPE_SEMESTER1_FINAL, Grade.TYPE_SEMESTER2_FINAL -> app.getString(R.string.grade_semester_final_format_2, grade.name) Grade.TYPE_SEMESTER1_FINAL, Grade.TYPE_SEMESTER2_FINAL -> app.getString(R.string.grade_semester_final_format_2, grade.name)
@ -144,7 +144,7 @@ class Notifications(val app: App, val notifications: MutableList<Notification>,
} }
private fun behaviourNotifications() { private fun behaviourNotifications() {
for (notice in app.db.noticeDao().notNotifiedNow) { for (notice in app.db.noticeDao().getNotNotifiedNow()) {
val noticeTypeStr = when (notice.type) { val noticeTypeStr = when (notice.type) {
Notice.TYPE_POSITIVE -> app.getString(R.string.notification_notice_praise) Notice.TYPE_POSITIVE -> app.getString(R.string.notification_notice_praise)
@ -155,7 +155,7 @@ class Notifications(val app: App, val notifications: MutableList<Notification>,
val text = app.getString( val text = app.getString(
R.string.notification_notice_format, R.string.notification_notice_format,
noticeTypeStr, noticeTypeStr,
notice.teacherFullName, notice.teacherName,
Date.fromMillis(notice.addedDate).formattedString Date.fromMillis(notice.addedDate).formattedString
) )
notifications += Notification( notifications += Notification(
@ -172,9 +172,9 @@ class Notifications(val app: App, val notifications: MutableList<Notification>,
} }
private fun attendanceNotifications() { private fun attendanceNotifications() {
for (attendance in app.db.attendanceDao().notNotifiedNow) { for (attendance in app.db.attendanceDao().getNotNotifiedNow()) {
val attendanceTypeStr = when (attendance.type) { val attendanceTypeStr = when (attendance.baseType) {
Attendance.TYPE_ABSENT -> app.getString(R.string.notification_absence) Attendance.TYPE_ABSENT -> app.getString(R.string.notification_absence)
Attendance.TYPE_ABSENT_EXCUSED -> app.getString(R.string.notification_absence_excused) Attendance.TYPE_ABSENT_EXCUSED -> app.getString(R.string.notification_absence_excused)
Attendance.TYPE_BELATED -> app.getString(R.string.notification_belated) Attendance.TYPE_BELATED -> app.getString(R.string.notification_belated)
@ -191,7 +191,7 @@ class Notifications(val app: App, val notifications: MutableList<Notification>,
R.string.notification_attendance_format, R.string.notification_attendance_format,
attendanceTypeStr, attendanceTypeStr,
attendance.subjectLongName, attendance.subjectLongName,
attendance.lessonDate.formattedString attendance.date.formattedString
) )
notifications += Notification( notifications += Notification(
id = Notification.buildId(attendance.profileId, Notification.TYPE_NEW_ATTENDANCE, attendance.id), id = Notification.buildId(attendance.profileId, Notification.TYPE_NEW_ATTENDANCE, attendance.id),
@ -207,10 +207,10 @@ class Notifications(val app: App, val notifications: MutableList<Notification>,
} }
private fun announcementNotifications() { private fun announcementNotifications() {
for (announcement in app.db.announcementDao().notNotifiedNow) { for (announcement in app.db.announcementDao().getNotNotifiedNow()) {
val text = app.getString( val text = app.getString(
R.string.notification_announcement_format, R.string.notification_announcement_format,
announcement.teacherFullName, announcement.teacherName,
announcement.subject announcement.subject
) )
notifications += Notification( notifications += Notification(
@ -247,9 +247,9 @@ class Notifications(val app: App, val notifications: MutableList<Notification>,
} }
private fun luckyNumberNotifications() { private fun luckyNumberNotifications() {
val luckyNumbers = app.db.luckyNumberDao().notNotifiedNow val luckyNumbers = app.db.luckyNumberDao().getNotNotifiedNow().toMutableList()
luckyNumbers?.removeAll { it.date < today } luckyNumbers.removeAll { it.date < today }
luckyNumbers?.forEach { luckyNumber -> luckyNumbers.forEach { luckyNumber ->
val profile = profiles.singleOrNull { it.id == luckyNumber.profileId } ?: return@forEach val profile = profiles.singleOrNull { it.id == luckyNumber.profileId } ?: return@forEach
val text = when (profile.studentNumber != -1 && profile.studentNumber == luckyNumber.number) { val text = when (profile.studentNumber != -1 && profile.studentNumber == luckyNumber.number) {
true -> when (luckyNumber.date.value) { true -> when (luckyNumber.date.value) {
@ -271,7 +271,7 @@ class Notifications(val app: App, val notifications: MutableList<Notification>,
profileId = luckyNumber.profileId, profileId = luckyNumber.profileId,
profileName = profile.name, profileName = profile.name,
viewId = MainActivity.DRAWER_ITEM_HOME, viewId = MainActivity.DRAWER_ITEM_HOME,
addedDate = luckyNumber.addedDate addedDate = System.currentTimeMillis()
) )
} }
} }
@ -280,7 +280,7 @@ class Notifications(val app: App, val notifications: MutableList<Notification>,
for (teacherAbsence in app.db.teacherAbsenceDao().getNotNotifiedNow()) { for (teacherAbsence in app.db.teacherAbsenceDao().getNotNotifiedNow()) {
val message = app.getString( val message = app.getString(
R.string.notification_teacher_absence_new_format, R.string.notification_teacher_absence_new_format,
teacherAbsence.teacherFullName teacherAbsence.teacherName
) )
notifications += Notification( notifications += Notification(
id = Notification.buildId(teacherAbsence.profileId, Notification.TYPE_TEACHER_ABSENCE, teacherAbsence.id), id = Notification.buildId(teacherAbsence.profileId, Notification.TYPE_TEACHER_ABSENCE, teacherAbsence.id),

View File

@ -43,7 +43,7 @@ import pl.szczodrzynski.edziennik.data.db.migration.*
LibrusLesson::class, LibrusLesson::class,
TimetableManual::class, TimetableManual::class,
Metadata::class Metadata::class
], version = 85) ], version = 86)
@TypeConverters( @TypeConverters(
ConverterTime::class, ConverterTime::class,
ConverterDate::class, ConverterDate::class,
@ -170,7 +170,8 @@ abstract class AppDb : RoomDatabase() {
Migration82(), Migration82(),
Migration83(), Migration83(),
Migration84(), Migration84(),
Migration85() Migration85(),
Migration86()
).allowMainThreadQueries().build() ).allowMainThreadQueries().build()
} }
} }

View File

@ -1,82 +0,0 @@
/*
* Copyright (c) Kacper Ziubryniewicz 2020-1-6
*/
package pl.szczodrzynski.edziennik.data.db.dao;
import androidx.lifecycle.LiveData;
import androidx.room.Dao;
import androidx.room.Insert;
import androidx.room.OnConflictStrategy;
import androidx.room.Query;
import androidx.room.RawQuery;
import androidx.sqlite.db.SimpleSQLiteQuery;
import androidx.sqlite.db.SupportSQLiteQuery;
import java.util.List;
import pl.szczodrzynski.edziennik.data.db.entity.Announcement;
import pl.szczodrzynski.edziennik.data.db.entity.Metadata;
import pl.szczodrzynski.edziennik.data.db.full.AnnouncementFull;
import static pl.szczodrzynski.edziennik.data.db.entity.Metadata.TYPE_ANNOUNCEMENT;
@Dao
public abstract class AnnouncementDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
public abstract long add(Announcement announcement);
@Insert(onConflict = OnConflictStrategy.REPLACE)
public abstract void addAll(List<Announcement> announcementList);
@Insert(onConflict = OnConflictStrategy.IGNORE)
public abstract void addAllIgnore(List<Announcement> announcementList);
@Query("DELETE FROM announcements WHERE profileId = :profileId")
public abstract void clear(int profileId);
@RawQuery(observedEntities = {Announcement.class, Metadata.class})
abstract LiveData<List<AnnouncementFull>> getAll(SupportSQLiteQuery query);
public LiveData<List<AnnouncementFull>> getAll(int profileId, String filter) {
return getAll(new SimpleSQLiteQuery("SELECT \n" +
"*, \n" +
"teachers.teacherName || ' ' || teachers.teacherSurname AS teacherFullName\n" +
"FROM announcements \n" +
"LEFT JOIN teachers USING(profileId, teacherId)\n" +
"LEFT JOIN metadata ON announcementId = thingId AND thingType = "+TYPE_ANNOUNCEMENT+" AND metadata.profileId = "+profileId+"\n" +
"WHERE announcements.profileId = "+profileId+" AND "+filter+"\n" +
"ORDER BY addedDate DESC"));
}
public LiveData<List<AnnouncementFull>> getAll(int profileId) {
return getAll(profileId, "1");
}
public LiveData<List<AnnouncementFull>> getAllWhere(int profileId, String filter) {
return getAll(profileId, filter);
}
@RawQuery(observedEntities = {Announcement.class, Metadata.class})
abstract List<AnnouncementFull> getAllNow(SupportSQLiteQuery query);
public List<AnnouncementFull> getAllNow(int profileId, String filter) {
return getAllNow(new SimpleSQLiteQuery("SELECT \n" +
"*, \n" +
"teachers.teacherName || ' ' || teachers.teacherSurname AS teacherFullName\n" +
"FROM announcements \n" +
"LEFT JOIN teachers USING(profileId, teacherId)\n" +
"LEFT JOIN metadata ON announcementId = thingId AND thingType = "+TYPE_ANNOUNCEMENT+" AND metadata.profileId = "+profileId+"\n" +
"WHERE announcements.profileId = "+profileId+" AND "+filter+"\n" +
"ORDER BY addedDate DESC"));
}
public List<AnnouncementFull> getNotNotifiedNow(int profileId) {
return getAllNow(profileId, "notified = 0");
}
@Query("SELECT " +
"*, " +
"teachers.teacherName || ' ' || teachers.teacherSurname AS teacherFullName " +
"FROM announcements " +
"LEFT JOIN teachers USING(profileId, teacherId) " +
"LEFT JOIN metadata ON announcementId = thingId AND thingType = "+TYPE_ANNOUNCEMENT+" AND metadata.profileId = announcements.profileId " +
"WHERE notified = 0 " +
"ORDER BY addedDate DESC")
public abstract List<AnnouncementFull> getNotNotifiedNow();
}

View File

@ -0,0 +1,69 @@
/*
* Copyright (c) Kuba Szczodrzyński 2020-4-25.
*/
package pl.szczodrzynski.edziennik.data.db.dao
import androidx.lifecycle.LiveData
import androidx.room.Dao
import androidx.room.Query
import androidx.room.RawQuery
import androidx.sqlite.db.SupportSQLiteQuery
import pl.szczodrzynski.edziennik.App
import pl.szczodrzynski.edziennik.annotation.SelectiveDao
import pl.szczodrzynski.edziennik.annotation.UpdateSelective
import pl.szczodrzynski.edziennik.data.db.AppDb
import pl.szczodrzynski.edziennik.data.db.entity.Announcement
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
import pl.szczodrzynski.edziennik.data.db.full.AnnouncementFull
@Dao
@SelectiveDao(db = AppDb::class)
abstract class AnnouncementDao : BaseDao<Announcement, AnnouncementFull> {
companion object {
private const val QUERY = """
SELECT
*,
teachers.teacherName ||" "|| teachers.teacherSurname AS teacherName
FROM announcements
LEFT JOIN teachers USING(profileId, teacherId)
LEFT JOIN metadata ON announcementId = thingId AND thingType = ${Metadata.TYPE_ANNOUNCEMENT} AND metadata.profileId = announcements.profileId
"""
private const val ORDER_BY = """ORDER BY addedDate DESC"""
}
private val selective by lazy { AnnouncementDaoSelective(App.db) }
@RawQuery(observedEntities = [Announcement::class])
abstract override fun getRaw(query: SupportSQLiteQuery): LiveData<List<AnnouncementFull>>
@RawQuery(observedEntities = [Announcement::class])
abstract override fun getOne(query: SupportSQLiteQuery): LiveData<AnnouncementFull?>
// SELECTIVE UPDATE
@UpdateSelective(primaryKeys = ["profileId", "announcementId"], skippedColumns = ["addedDate", "announcementText"])
override fun update(item: Announcement) = selective.update(item)
override fun updateAll(items: List<Announcement>) = selective.updateAll(items)
// CLEAR
@Query("DELETE FROM announcements WHERE profileId = :profileId")
abstract override fun clear(profileId: Int)
// REMOVE NOT KEPT
@Query("DELETE FROM announcements WHERE keep = 0")
abstract override fun removeNotKept()
// GET ALL - LIVE DATA
fun getAll(profileId: Int) =
getRaw("$QUERY WHERE announcements.profileId = $profileId $ORDER_BY")
// GET ALL - NOW
fun getAllNow(profileId: Int) =
getRawNow("$QUERY WHERE announcements.profileId = $profileId $ORDER_BY")
fun getNotNotifiedNow() =
getRawNow("$QUERY WHERE notified = 0 $ORDER_BY")
fun getNotNotifiedNow(profileId: Int) =
getRawNow("$QUERY WHERE announcements.profileId = $profileId AND notified = 0 $ORDER_BY")
// GET ONE - NOW
fun getByIdNow(profileId: Int, id: Long) =
getOneNow("$QUERY WHERE announcements.profileId = $profileId AND announcementId = $id")
}

View File

@ -1,108 +0,0 @@
/*
* Copyright (c) Kacper Ziubryniewicz 2020-1-6
*/
package pl.szczodrzynski.edziennik.data.db.dao;
import androidx.lifecycle.LiveData;
import androidx.room.Dao;
import androidx.room.Insert;
import androidx.room.OnConflictStrategy;
import androidx.room.Query;
import androidx.room.RawQuery;
import androidx.sqlite.db.SimpleSQLiteQuery;
import androidx.sqlite.db.SupportSQLiteQuery;
import java.util.List;
import pl.szczodrzynski.edziennik.data.db.entity.Attendance;
import pl.szczodrzynski.edziennik.data.db.full.AttendanceFull;
import pl.szczodrzynski.edziennik.utils.models.Date;
import static pl.szczodrzynski.edziennik.data.db.entity.Metadata.TYPE_ATTENDANCE;
@Dao
public abstract class AttendanceDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
public abstract long add(Attendance attendance);
@Insert(onConflict = OnConflictStrategy.REPLACE)
public abstract void addAll(List<Attendance> attendanceList);
@Query("DELETE FROM attendances WHERE profileId = :profileId")
public abstract void clear(int profileId);
@Query("DELETE FROM attendances WHERE profileId = :profileId AND attendanceLessonDate > :date")
public abstract void clearAfterDate(int profileId, Date date);
@RawQuery(observedEntities = {Attendance.class})
abstract LiveData<List<AttendanceFull>> getAll(SupportSQLiteQuery query);
public LiveData<List<AttendanceFull>> getAll(int profileId, String filter) {
return getAll(new SimpleSQLiteQuery("SELECT \n" +
"*, \n" +
"teachers.teacherName || ' ' || teachers.teacherSurname AS teacherFullName\n" +
"FROM attendances \n" +
"LEFT JOIN teachers USING(profileId, teacherId)\n" +
"LEFT JOIN subjects USING(profileId, subjectId)\n" +
"LEFT JOIN metadata ON attendanceId = thingId AND thingType = " + TYPE_ATTENDANCE + " AND metadata.profileId = "+profileId+"\n" +
"WHERE attendances.profileId = "+profileId+" AND "+filter+"\n" +
"ORDER BY attendanceLessonDate DESC, attendanceStartTime DESC"));
}
public LiveData<List<AttendanceFull>> getAll(int profileId) {
return getAll(profileId, "1");
}
public LiveData<List<AttendanceFull>> getAllWhere(int profileId, String filter) {
return getAll(profileId, filter);
}
@RawQuery
abstract List<AttendanceFull> getAllNow(SupportSQLiteQuery query);
public List<AttendanceFull> getAllNow(int profileId, String filter) {
return getAllNow(new SimpleSQLiteQuery("SELECT \n" +
"*, \n" +
"teachers.teacherName || ' ' || teachers.teacherSurname AS teacherFullName\n" +
"FROM attendances \n" +
"LEFT JOIN teachers USING(profileId, teacherId)\n" +
"LEFT JOIN subjects USING(profileId, subjectId)\n" +
"LEFT JOIN metadata ON attendanceId = thingId AND thingType = " + TYPE_ATTENDANCE + " AND metadata.profileId = "+profileId+"\n" +
"WHERE attendances.profileId = "+profileId+" AND "+filter+"\n" +
"ORDER BY attendanceLessonDate DESC, attendanceStartTime DESC"));
}
public List<AttendanceFull> getNotNotifiedNow(int profileId) {
return getAllNow(profileId, "notified = 0");
}
@Query("SELECT * FROM attendances " +
"LEFT JOIN subjects USING(profileId, subjectId) " +
"LEFT JOIN metadata ON attendanceId = thingId AND thingType = " + TYPE_ATTENDANCE + " AND metadata.profileId = attendances.profileId " +
"WHERE notified = 0 " +
"ORDER BY attendanceLessonDate DESC, attendanceStartTime DESC")
public abstract List<AttendanceFull> getNotNotifiedNow();
// only absent and absent_excused count as absences
// all the other types are counted as being present
@Query("SELECT \n" +
"CAST(SUM(CASE WHEN attendanceType != "+Attendance.TYPE_ABSENT+" AND attendanceType != "+ Attendance.TYPE_ABSENT_EXCUSED+" THEN 1 ELSE 0 END) AS float)\n" +
" / \n" +
"CAST(count() AS float)*100 \n" +
"FROM attendances \n" +
"WHERE profileId = :profileId")
public abstract LiveData<Float> getAttendancePercentage(int profileId);
@Query("SELECT \n" +
"CAST(SUM(CASE WHEN attendanceType != "+Attendance.TYPE_ABSENT+" AND attendanceType != "+Attendance.TYPE_ABSENT_EXCUSED+" THEN 1 ELSE 0 END) AS float)\n" +
" / \n" +
"CAST(count() AS float)*100 \n" +
"FROM attendances \n" +
"WHERE profileId = :profileId AND attendanceSemester = :semester")
public abstract float getAttendancePercentageNow(int profileId, int semester);
@Query("SELECT \n" +
"CAST(SUM(CASE WHEN attendanceType != "+Attendance.TYPE_ABSENT+" AND attendanceType != "+Attendance.TYPE_ABSENT_EXCUSED+" THEN 1 ELSE 0 END) AS float)\n" +
" / \n" +
"CAST(count() AS float)*100 \n" +
"FROM attendances \n" +
"WHERE profileId = :profileId")
public abstract float getAttendancePercentageNow(int profileId);
}

View File

@ -0,0 +1,74 @@
/*
* Copyright (c) Kuba Szczodrzyński 2020-4-24.
*/
package pl.szczodrzynski.edziennik.data.db.dao
import androidx.lifecycle.LiveData
import androidx.room.Dao
import androidx.room.Query
import androidx.room.RawQuery
import androidx.sqlite.db.SupportSQLiteQuery
import pl.szczodrzynski.edziennik.App
import pl.szczodrzynski.edziennik.annotation.SelectiveDao
import pl.szczodrzynski.edziennik.annotation.UpdateSelective
import pl.szczodrzynski.edziennik.data.db.AppDb
import pl.szczodrzynski.edziennik.data.db.entity.Attendance
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
import pl.szczodrzynski.edziennik.data.db.full.AttendanceFull
import pl.szczodrzynski.edziennik.utils.models.Date
@Dao
@SelectiveDao(db = AppDb::class)
abstract class AttendanceDao : BaseDao<Attendance, AttendanceFull> {
companion object {
private const val QUERY = """
SELECT
*,
teachers.teacherName ||" "|| teachers.teacherSurname AS teacherName
FROM attendances
LEFT JOIN teachers USING(profileId, teacherId)
LEFT JOIN subjects USING(profileId, subjectId)
LEFT JOIN metadata ON attendanceId = thingId AND thingType = ${Metadata.TYPE_ATTENDANCE} AND metadata.profileId = attendances.profileId
"""
private const val ORDER_BY = """ORDER BY attendanceDate DESC, attendanceTime DESC"""
}
private val selective by lazy { AttendanceDaoSelective(App.db) }
@RawQuery(observedEntities = [Attendance::class])
abstract override fun getRaw(query: SupportSQLiteQuery): LiveData<List<AttendanceFull>>
@RawQuery(observedEntities = [Attendance::class])
abstract override fun getOne(query: SupportSQLiteQuery): LiveData<AttendanceFull?>
// SELECTIVE UPDATE
@UpdateSelective(primaryKeys = ["profileId", "attendanceId"], skippedColumns = ["addedDate", "announcementText"])
override fun update(item: Attendance) = selective.update(item)
override fun updateAll(items: List<Attendance>) = selective.updateAll(items)
// CLEAR
@Query("DELETE FROM attendances WHERE profileId = :profileId")
abstract override fun clear(profileId: Int)
// REMOVE NOT KEPT
@Query("DELETE FROM attendances WHERE keep = 0")
abstract override fun removeNotKept()
// GET ALL - LIVE DATA
fun getAll(profileId: Int) =
getRaw("$QUERY WHERE attendances.profileId = $profileId $ORDER_BY")
// GET ALL - NOW
fun getAllNow(profileId: Int) =
getRawNow("$QUERY WHERE attendances.profileId = $profileId $ORDER_BY")
fun getNotNotifiedNow() =
getRawNow("$QUERY WHERE notified = 0 $ORDER_BY")
fun getNotNotifiedNow(profileId: Int) =
getRawNow("$QUERY WHERE attendances.profileId = $profileId AND notified = 0 $ORDER_BY")
// GET ONE - NOW
fun getByIdNow(profileId: Int, id: Long) =
getOneNow("$QUERY WHERE attendances.profileId = $profileId AND attendanceId = $id")
@Query("UPDATE attendances SET keep = 0 WHERE profileId = :profileId AND attendanceDate > :date")
abstract fun dontKeepAfterDate(profileId: Int, date: Date?)
}

View File

@ -16,13 +16,15 @@ interface BaseDao<T : Keepable, F : T> {
fun getRaw(query: SupportSQLiteQuery): LiveData<List<F>> fun getRaw(query: SupportSQLiteQuery): LiveData<List<F>>
fun getRaw(query: String) = getRaw(SimpleSQLiteQuery(query)) fun getRaw(query: String) = getRaw(SimpleSQLiteQuery(query))
@RawQuery @RawQuery
fun getOne(query: SupportSQLiteQuery): LiveData<F?>
fun getOne(query: String) = getOne(SimpleSQLiteQuery(query))
@RawQuery
fun getRawNow(query: SupportSQLiteQuery): List<F> fun getRawNow(query: SupportSQLiteQuery): List<F>
fun getRawNow(query: String) = getRawNow(SimpleSQLiteQuery(query)) fun getRawNow(query: String) = getRawNow(SimpleSQLiteQuery(query))
@RawQuery @RawQuery
fun getOneNow(query: SupportSQLiteQuery): F? fun getOneNow(query: SupportSQLiteQuery): F?
fun getOneNow(query: String) = getOneNow(SimpleSQLiteQuery(query)) fun getOneNow(query: String) = getOneNow(SimpleSQLiteQuery(query))
@Query("DELETE FROM events WHERE keep = 0")
fun removeNotKept() fun removeNotKept()
/** /**
@ -41,12 +43,14 @@ interface BaseDao<T : Keepable, F : T> {
/** /**
* REPLACE an [item] in the database, * REPLACE an [item] in the database,
* removing any conflicting rows. * removing any conflicting rows.
* Creates the item if it does not exist yet.
*/ */
@Insert(onConflict = OnConflictStrategy.REPLACE) @Insert(onConflict = OnConflictStrategy.REPLACE)
fun replace(item: T) fun replace(item: T)
/** /**
* REPLACE [items] in the database, * REPLACE [items] in the database,
* removing any conflicting rows. * removing any conflicting rows.
* Creates items if it does not exist yet.
*/ */
@Insert(onConflict = OnConflictStrategy.REPLACE) @Insert(onConflict = OnConflictStrategy.REPLACE)
fun replaceAll(items: List<T>) fun replaceAll(items: List<T>)
@ -97,4 +101,21 @@ interface BaseDao<T : Keepable, F : T> {
if (removeNotKept) removeNotKept() if (removeNotKept) removeNotKept()
return insertResult return insertResult
} }
/**
* Make sure that [items] are in the database.
* When [forceReplace] == false, do a selective update (UPSERT).
* When [forceReplace] == true, add all items replacing any conflicting ones (REPLACE).
*
* @param forceReplace whether to replace all items instead of selectively updating
* @param removeNotKept whether to remove all items whose [keep] parameter is false
*/
fun putAll(items: List<T>, forceReplace: Boolean = false, removeNotKept: Boolean = false) {
if (items.isEmpty())
return
if (forceReplace)
replaceAll(items)
else
upsertAll(items)
}
} }

View File

@ -31,8 +31,8 @@ abstract class EventDao : BaseDao<Event, EventFull> {
eventTypes.eventTypeName AS typeName, eventTypes.eventTypeName AS typeName,
eventTypes.eventTypeColor AS typeColor eventTypes.eventTypeColor AS typeColor
FROM events FROM events
LEFT JOIN subjects USING(profileId, subjectId)
LEFT JOIN teachers USING(profileId, teacherId) LEFT JOIN teachers USING(profileId, teacherId)
LEFT JOIN subjects USING(profileId, subjectId)
LEFT JOIN teams USING(profileId, teamId) LEFT JOIN teams USING(profileId, teamId)
LEFT JOIN eventTypes USING(profileId, eventType) LEFT JOIN eventTypes USING(profileId, eventType)
LEFT JOIN metadata ON eventId = thingId AND (thingType = ${Metadata.TYPE_EVENT} OR thingType = ${Metadata.TYPE_HOMEWORK}) AND metadata.profileId = events.profileId LEFT JOIN metadata ON eventId = thingId AND (thingType = ${Metadata.TYPE_EVENT} OR thingType = ${Metadata.TYPE_HOMEWORK}) AND metadata.profileId = events.profileId
@ -47,6 +47,8 @@ abstract class EventDao : BaseDao<Event, EventFull> {
@RawQuery(observedEntities = [Event::class]) @RawQuery(observedEntities = [Event::class])
abstract override fun getRaw(query: SupportSQLiteQuery): LiveData<List<EventFull>> abstract override fun getRaw(query: SupportSQLiteQuery): LiveData<List<EventFull>>
@RawQuery(observedEntities = [Event::class])
abstract override fun getOne(query: SupportSQLiteQuery): LiveData<EventFull?>
// SELECTIVE UPDATE // SELECTIVE UPDATE
@UpdateSelective(primaryKeys = ["profileId", "eventId"], skippedColumns = ["eventIsDone", "eventBlacklisted", "homeworkBody", "attachmentIds", "attachmentNames"]) @UpdateSelective(primaryKeys = ["profileId", "eventId"], skippedColumns = ["eventIsDone", "eventBlacklisted", "homeworkBody", "attachmentIds", "attachmentNames"])
@ -56,6 +58,9 @@ abstract class EventDao : BaseDao<Event, EventFull> {
// CLEAR // CLEAR
@Query("DELETE FROM events WHERE profileId = :profileId") @Query("DELETE FROM events WHERE profileId = :profileId")
abstract override fun clear(profileId: Int) abstract override fun clear(profileId: Int)
// REMOVE NOT KEPT
@Query("DELETE FROM events WHERE keep = 0")
abstract override fun removeNotKept()
// GET ALL - LIVE DATA // GET ALL - LIVE DATA
fun getAll(profileId: Int) = fun getAll(profileId: Int) =

View File

@ -1,32 +1,86 @@
/* /*
* Copyright (c) Kacper Ziubryniewicz 2020-1-6 * Copyright (c) Kuba Szczodrzyński 2020-4-24.
*/ */
package pl.szczodrzynski.edziennik.data.db.dao package pl.szczodrzynski.edziennik.data.db.dao
import androidx.lifecycle.LiveData import androidx.lifecycle.LiveData
import androidx.room.* import androidx.room.Dao
import androidx.sqlite.db.SimpleSQLiteQuery import androidx.room.Query
import androidx.room.RawQuery
import androidx.room.Transaction
import androidx.sqlite.db.SupportSQLiteQuery import androidx.sqlite.db.SupportSQLiteQuery
import pl.szczodrzynski.edziennik.App
import pl.szczodrzynski.edziennik.annotation.SelectiveDao
import pl.szczodrzynski.edziennik.annotation.UpdateSelective
import pl.szczodrzynski.edziennik.data.db.AppDb
import pl.szczodrzynski.edziennik.data.db.entity.Grade import pl.szczodrzynski.edziennik.data.db.entity.Grade
import pl.szczodrzynski.edziennik.data.db.entity.Metadata import pl.szczodrzynski.edziennik.data.db.entity.Metadata
import pl.szczodrzynski.edziennik.data.db.full.GradeFull import pl.szczodrzynski.edziennik.data.db.full.GradeFull
import pl.szczodrzynski.edziennik.utils.models.Date
import java.util.* import java.util.*
import kotlin.collections.List
import kotlin.collections.component1 import kotlin.collections.component1
import kotlin.collections.component2 import kotlin.collections.component2
import kotlin.collections.iterator
import kotlin.collections.set import kotlin.collections.set
@Dao @Dao
abstract class GradeDao { @SelectiveDao(db = AppDb::class)
@Insert(onConflict = OnConflictStrategy.REPLACE) abstract class GradeDao : BaseDao<Grade, GradeFull> {
abstract fun add(grade: Grade): Long companion object {
private const val QUERY = """
SELECT
*,
teachers.teacherName ||" "|| teachers.teacherSurname AS teacherName
FROM grades
LEFT JOIN teachers USING(profileId, teacherId)
LEFT JOIN subjects USING(profileId, subjectId)
LEFT JOIN metadata ON gradeId = thingId AND thingType = ${Metadata.TYPE_GRADE} AND metadata.profileId = grades.profileId
"""
@Insert(onConflict = OnConflictStrategy.REPLACE) private const val ORDER_BY = """ORDER BY addedDate DESC"""
abstract fun addAll(gradeList: List<Grade>) }
private val selective by lazy { GradeDaoSelective(App.db) }
@RawQuery(observedEntities = [Grade::class])
abstract override fun getRaw(query: SupportSQLiteQuery): LiveData<List<GradeFull>>
@RawQuery(observedEntities = [Grade::class])
abstract override fun getOne(query: SupportSQLiteQuery): LiveData<GradeFull?>
// SELECTIVE UPDATE
@UpdateSelective(primaryKeys = ["profileId", "gradeId"], skippedColumns = ["addedDate", "gradeClassAverage"])
override fun update(item: Grade) = selective.update(item)
override fun updateAll(items: List<Grade>) = selective.updateAll(items)
// CLEAR
@Query("DELETE FROM grades WHERE profileId = :profileId") @Query("DELETE FROM grades WHERE profileId = :profileId")
abstract fun clear(profileId: Int) abstract override fun clear(profileId: Int)
// REMOVE NOT KEPT
@Query("DELETE FROM grades WHERE keep = 0")
abstract override fun removeNotKept()
// GET ALL - LIVE DATA
fun getAll(profileId: Int) =
getRaw("$QUERY WHERE grades.profileId = $profileId $ORDER_BY")
fun getAllFromDate(profileId: Int, date: Date) =
getRaw("$QUERY WHERE grades.profileId = $profileId AND addedDate > ${date.inMillis} $ORDER_BY")
fun getAllBySubject(profileId: Int, subjectId: Long) =
getRaw("$QUERY WHERE grades.profileId = $profileId AND subjectId = $subjectId $ORDER_BY")
fun getAllOrderBy(profileId: Int, orderBy: String) =
getRaw("$QUERY WHERE grades.profileId = $profileId ORDER BY $orderBy")
// GET ALL - NOW
fun getAllNow(profileId: Int) =
getRawNow("$QUERY WHERE grades.profileId = $profileId $ORDER_BY")
fun getNotNotifiedNow() =
getRawNow("$QUERY WHERE notified = 0 $ORDER_BY")
fun getNotNotifiedNow(profileId: Int) =
getRawNow("$QUERY WHERE grades.profileId = $profileId AND notified = 0 $ORDER_BY")
fun getByParentIdNow(profileId: Int, parentId: Long) =
getRawNow("$QUERY WHERE grades.profileId = $profileId AND gradeParentId = $parentId $ORDER_BY")
// GET ONE - NOW
fun getByIdNow(profileId: Int, id: Long) =
getOneNow("$QUERY WHERE grades.profileId = $profileId AND gradeId = $id")
@Query("DELETE FROM grades WHERE profileId = :profileId AND gradeType = :type") @Query("DELETE FROM grades WHERE profileId = :profileId AND gradeType = :type")
abstract fun clearWithType(profileId: Int, type: Int) abstract fun clearWithType(profileId: Int, type: Int)
@ -37,66 +91,13 @@ abstract class GradeDao {
@Query("DELETE FROM grades WHERE profileId = :profileId AND gradeSemester = :semester AND gradeType = :type") @Query("DELETE FROM grades WHERE profileId = :profileId AND gradeSemester = :semester AND gradeType = :type")
abstract fun clearForSemesterWithType(profileId: Int, semester: Int, type: Int) abstract fun clearForSemesterWithType(profileId: Int, semester: Int, type: Int)
@RawQuery(observedEntities = [Grade::class])
abstract fun getAll(query: SupportSQLiteQuery?): LiveData<List<GradeFull>>
fun getAll(profileId: Int, filter: String, orderBy: String): LiveData<List<GradeFull>> {
return getAll(SimpleSQLiteQuery("SELECT \n" +
"*, \n" +
"teachers.teacherName || ' ' || teachers.teacherSurname AS teacherFullName\n" +
"FROM grades \n" +
"LEFT JOIN subjects USING(profileId, subjectId)\n" +
"LEFT JOIN teachers USING(profileId, teacherId)\n" +
"LEFT JOIN metadata ON gradeId = thingId AND thingType = " + Metadata.TYPE_GRADE + " AND metadata.profileId = " + profileId + "\n" +
"WHERE grades.profileId = " + profileId + " AND " + filter + "\n" +
"ORDER BY " + orderBy)) // TODO: 2019-04-30 why did I add sorting by gradeType???
}
fun getAllOrderBy(profileId: Int, orderBy: String): LiveData<List<GradeFull>> {
return getAll(profileId, "1", orderBy)
}
fun getAllWhere(profileId: Int, filter: String): LiveData<List<GradeFull>> {
return getAll(profileId, filter, "addedDate DESC")
}
@RawQuery
abstract fun getAllNow(query: SupportSQLiteQuery?): List<GradeFull>
fun getAllNow(profileId: Int, filter: String): List<GradeFull> {
return getAllNow(SimpleSQLiteQuery("SELECT \n" +
"*, \n" +
"teachers.teacherName || ' ' || teachers.teacherSurname AS teacherFullName\n" +
"FROM grades \n" +
"LEFT JOIN subjects USING(profileId, subjectId)\n" +
"LEFT JOIN teachers USING(profileId, teacherId)\n" +
"LEFT JOIN metadata ON gradeId = thingId AND thingType = " + Metadata.TYPE_GRADE + " AND metadata.profileId = " + profileId + "\n" +
"WHERE grades.profileId = " + profileId + " AND " + filter + "\n" +
"ORDER BY addedDate DESC"))
}
fun getNotNotifiedNow(profileId: Int): List<GradeFull> {
return getAllNow(profileId, "notified = 0")
}
fun getAllWithParentIdNow(profileId: Int, parentId: Long): List<GradeFull> {
return getAllNow(profileId, "gradeParentId = $parentId")
}
@get:Query("SELECT * FROM grades " +
"LEFT JOIN subjects USING(profileId, subjectId) " +
"LEFT JOIN metadata ON gradeId = thingId AND thingType = " + Metadata.TYPE_GRADE + " AND metadata.profileId = grades.profileId " +
"WHERE notified = 0 " +
"ORDER BY addedDate DESC")
abstract val notNotifiedNow: List<GradeFull>
@RawQuery
abstract fun getNow(query: SupportSQLiteQuery): GradeFull?
// GRADE DETAILS - MOBIDZIENNIK
@Query("UPDATE grades SET gradeClassAverage = :classAverage, gradeColor = :color WHERE profileId = :profileId AND gradeId = :gradeId") @Query("UPDATE grades SET gradeClassAverage = :classAverage, gradeColor = :color WHERE profileId = :profileId AND gradeId = :gradeId")
abstract fun updateDetailsById(profileId: Int, gradeId: Long, classAverage: Float, color: Int) abstract fun updateDetailsById(profileId: Int, gradeId: Long, classAverage: Float, color: Int)
@Query("UPDATE metadata SET addedDate = :addedDate WHERE profileId = :profileId AND thingType = " + Metadata.TYPE_GRADE + " AND thingId = :gradeId") @Query("UPDATE grades SET addedDate = :addedDate WHERE profileId = :profileId AND gradeId = :gradeId")
abstract fun updateAddedDateById(profileId: Int, gradeId: Long, addedDate: Long) abstract fun updateAddedDateById(profileId: Int, gradeId: Long, addedDate: Long)
@Transaction @Transaction
@ -118,7 +119,7 @@ abstract class GradeDao {
@Query("SELECT gradeColor FROM grades WHERE profileId = :profileId ORDER BY gradeId") @Query("SELECT gradeColor FROM grades WHERE profileId = :profileId ORDER BY gradeId")
abstract fun getColors(profileId: Int): List<Int> abstract fun getColors(profileId: Int): List<Int>
@Query("SELECT addedDate FROM metadata WHERE profileId = :profileId AND thingType = " + Metadata.TYPE_GRADE + " ORDER BY thingId") @Query("SELECT addedDate FROM grades WHERE profileId = :profileId ORDER BY gradeId")
abstract fun getAddedDates(profileId: Int): List<Long> abstract fun getAddedDates(profileId: Int): List<Long>
@Transaction @Transaction
@ -134,8 +135,4 @@ abstract class GradeDao {
gradeAddedDates[gradeId] = addedDates.next() gradeAddedDates[gradeId] = addedDates.next()
} }
} }
fun getAllFromDate(profileId: Int, date: Long): LiveData<List<GradeFull>> {
return getAllWhere(profileId, "addedDate > $date")
}
} }

View File

@ -1,87 +0,0 @@
/*
* Copyright (c) Kacper Ziubryniewicz 2020-1-6
*/
package pl.szczodrzynski.edziennik.data.db.dao;
import androidx.annotation.Nullable;
import androidx.lifecycle.LiveData;
import androidx.room.Dao;
import androidx.room.Insert;
import androidx.room.OnConflictStrategy;
import androidx.room.Query;
import androidx.room.RawQuery;
import androidx.sqlite.db.SimpleSQLiteQuery;
import androidx.sqlite.db.SupportSQLiteQuery;
import java.util.List;
import pl.szczodrzynski.edziennik.data.db.entity.LuckyNumber;
import pl.szczodrzynski.edziennik.data.db.entity.Metadata;
import pl.szczodrzynski.edziennik.data.db.entity.Notice;
import pl.szczodrzynski.edziennik.data.db.full.LuckyNumberFull;
import pl.szczodrzynski.edziennik.utils.models.Date;
import static pl.szczodrzynski.edziennik.data.db.entity.Metadata.TYPE_LUCKY_NUMBER;
@Dao
public abstract class LuckyNumberDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
public abstract void add(LuckyNumber luckyNumber);
@Insert(onConflict = OnConflictStrategy.REPLACE)
public abstract void addAll(List<LuckyNumber> luckyNumberList);
@Query("DELETE FROM luckyNumbers WHERE profileId = :profileId")
public abstract void clear(int profileId);
@Query("SELECT * FROM luckyNumbers WHERE profileId = :profileId AND luckyNumberDate = :date")
public abstract LiveData<LuckyNumber> getByDate(int profileId, Date date);
@Query("SELECT * FROM luckyNumbers WHERE profileId = :profileId AND luckyNumberDate = :date")
public abstract LuckyNumber getByDateNow(int profileId, Date date);
@Nullable
@Query("SELECT * FROM luckyNumbers WHERE profileId = :profileId AND luckyNumberDate >= :date ORDER BY luckyNumberDate DESC LIMIT 1")
public abstract LuckyNumber getNearestFutureNow(int profileId, int date);
@Query("SELECT * FROM luckyNumbers WHERE profileId = :profileId AND luckyNumberDate >= :date ORDER BY luckyNumberDate DESC LIMIT 1")
public abstract LiveData<LuckyNumber> getNearestFuture(int profileId, int date);
@RawQuery(observedEntities = {LuckyNumber.class})
abstract LiveData<List<LuckyNumberFull>> getAll(SupportSQLiteQuery query);
public LiveData<List<LuckyNumberFull>> getAll(int profileId, String filter) {
return getAll(new SimpleSQLiteQuery("SELECT\n" +
"*\n" +
"FROM luckyNumbers\n" +
"LEFT JOIN metadata ON luckyNumberDate = thingId AND thingType = "+TYPE_LUCKY_NUMBER+" AND metadata.profileId = "+profileId+"\n" +
"WHERE luckyNumbers.profileId = "+profileId+" AND "+filter+"\n" +
"ORDER BY addedDate DESC"));
}
public LiveData<List<LuckyNumberFull>> getAll(int profileId) {
return getAll(profileId, "1");
}
public LiveData<List<LuckyNumberFull>> getAllWhere(int profileId, String filter) {
return getAll(profileId, filter);
}
@RawQuery(observedEntities = {Notice.class, Metadata.class})
abstract List<LuckyNumberFull> getAllNow(SupportSQLiteQuery query);
public List<LuckyNumberFull> getAllNow(int profileId, String filter) {
return getAllNow(new SimpleSQLiteQuery("SELECT\n" +
"*\n" +
"FROM luckyNumbers\n" +
"LEFT JOIN metadata ON luckyNumberDate = thingId AND thingType = "+TYPE_LUCKY_NUMBER+" AND metadata.profileId = "+profileId+"\n" +
"WHERE luckyNumbers.profileId = "+profileId+" AND "+filter+"\n" +
"ORDER BY addedDate DESC"));
}
public List<LuckyNumberFull> getNotNotifiedNow(int profileId) {
return getAllNow(profileId, "notified = 0");
}
@Query("SELECT * FROM luckyNumbers\n" +
"LEFT JOIN metadata ON luckyNumberDate = thingId AND thingType = "+TYPE_LUCKY_NUMBER+" AND metadata.profileId = luckyNumbers.profileId " +
"WHERE notified = 0 " +
"ORDER BY addedDate DESC")
public abstract List<LuckyNumberFull> getNotNotifiedNow();
}

View File

@ -0,0 +1,74 @@
/*
* Copyright (c) Kuba Szczodrzyński 2020-4-25.
*/
package pl.szczodrzynski.edziennik.data.db.dao
import androidx.lifecycle.LiveData
import androidx.room.Dao
import androidx.room.Query
import androidx.room.RawQuery
import androidx.sqlite.db.SupportSQLiteQuery
import pl.szczodrzynski.edziennik.App
import pl.szczodrzynski.edziennik.annotation.SelectiveDao
import pl.szczodrzynski.edziennik.annotation.UpdateSelective
import pl.szczodrzynski.edziennik.data.db.AppDb
import pl.szczodrzynski.edziennik.data.db.entity.LuckyNumber
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
import pl.szczodrzynski.edziennik.data.db.full.LuckyNumberFull
import pl.szczodrzynski.edziennik.utils.models.Date
@Dao
@SelectiveDao(db = AppDb::class)
abstract class LuckyNumberDao : BaseDao<LuckyNumber, LuckyNumberFull> {
companion object {
private const val QUERY = """
SELECT
*
FROM luckyNumbers
LEFT JOIN metadata ON luckyNumberDate = thingId AND thingType = ${Metadata.TYPE_LUCKY_NUMBER} AND metadata.profileId = luckyNumbers.profileId
"""
private const val ORDER_BY = """ORDER BY luckyNumberDate DESC"""
}
private val selective by lazy { LuckyNumberDaoSelective(App.db) }
@RawQuery(observedEntities = [LuckyNumber::class])
abstract override fun getRaw(query: SupportSQLiteQuery): LiveData<List<LuckyNumberFull>>
@RawQuery(observedEntities = [LuckyNumber::class])
abstract override fun getOne(query: SupportSQLiteQuery): LiveData<LuckyNumberFull?>
// SELECTIVE UPDATE
@UpdateSelective(primaryKeys = ["profileId", "luckyNumberDate"], skippedColumns = ["addedDate"])
override fun update(item: LuckyNumber) = selective.update(item)
override fun updateAll(items: List<LuckyNumber>) = selective.updateAll(items)
// CLEAR
@Query("DELETE FROM luckyNumbers WHERE profileId = :profileId")
abstract override fun clear(profileId: Int)
// REMOVE NOT KEPT
@Query("DELETE FROM luckyNumbers WHERE keep = 0")
abstract override fun removeNotKept()
// GET ALL - LIVE DATA
fun getAll(profileId: Int) =
getRaw("$QUERY WHERE luckyNumbers.profileId = $profileId $ORDER_BY")
// GET ALL - NOW
fun getAllNow(profileId: Int) =
getRawNow("$QUERY WHERE luckyNumbers.profileId = $profileId $ORDER_BY")
fun getNotNotifiedNow() =
getRawNow("$QUERY WHERE notified = 0 $ORDER_BY")
fun getNotNotifiedNow(profileId: Int) =
getRawNow("$QUERY WHERE luckyNumbers.profileId = $profileId AND notified = 0 $ORDER_BY")
// GET ONE - LIVE DATA
fun getNearestFuture(profileId: Int, today: Date) =
getOne("$QUERY WHERE luckyNumbers.profileId = $profileId AND luckyNumberDate >= ${today.value} $ORDER_BY LIMIT 1")
// GET ONE - NOW
fun getByIdNow(profileId: Int, id: Long) =
getOneNow("$QUERY WHERE attendances.profileId = $profileId AND attendanceId = $id")
fun getNearestFutureNow(profileId: Int, today: Date) =
getOneNow("$QUERY WHERE luckyNumbers.profileId = $profileId AND luckyNumberDate >= ${today.value} $ORDER_BY LIMIT 1")
}

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) Kacper Ziubryniewicz 2020-1-6 * Copyright (c) Kuba Szczodrzyński 2020-4-25.
*/ */
package pl.szczodrzynski.edziennik.data.db.dao package pl.szczodrzynski.edziennik.data.db.dao
@ -36,7 +36,10 @@ abstract class MessageDao : BaseDao<Message, MessageFull> {
@RawQuery(observedEntities = [Message::class]) @RawQuery(observedEntities = [Message::class])
abstract override fun getRaw(query: SupportSQLiteQuery): LiveData<List<MessageFull>> abstract override fun getRaw(query: SupportSQLiteQuery): LiveData<List<MessageFull>>
@RawQuery(observedEntities = [Message::class])
abstract override fun getOne(query: SupportSQLiteQuery): LiveData<MessageFull?>
// SELECTIVE UPDATE
@UpdateSelective(primaryKeys = ["profileId", "messageId"], skippedColumns = ["messageType", "messageBody", "messageIsPinned", "attachmentIds", "attachmentNames", "attachmentSizes"]) @UpdateSelective(primaryKeys = ["profileId", "messageId"], skippedColumns = ["messageType", "messageBody", "messageIsPinned", "attachmentIds", "attachmentNames", "attachmentSizes"])
override fun update(item: Message) = selective.update(item) override fun update(item: Message) = selective.update(item)
override fun updateAll(items: List<Message>) = selective.updateAll(items) override fun updateAll(items: List<Message>) = selective.updateAll(items)
@ -44,6 +47,9 @@ abstract class MessageDao : BaseDao<Message, MessageFull> {
// CLEAR // CLEAR
@Query("DELETE FROM messages WHERE profileId = :profileId") @Query("DELETE FROM messages WHERE profileId = :profileId")
abstract override fun clear(profileId: Int) abstract override fun clear(profileId: Int)
// REMOVE NOT KEPT
@Query("DELETE FROM messages WHERE keep = 0")
abstract override fun removeNotKept()
// GET ALL - LIVE DATA // GET ALL - LIVE DATA
fun getAll(profileId: Int) = fun getAll(profileId: Int) =
@ -64,4 +70,6 @@ abstract class MessageDao : BaseDao<Message, MessageFull> {
// GET ONE - NOW // GET ONE - NOW
fun getByIdNow(profileId: Int, id: Long) = fun getByIdNow(profileId: Int, id: Long) =
getOneNow("$QUERY WHERE messages.profileId = $profileId AND messageId = $id") getOneNow("$QUERY WHERE messages.profileId = $profileId AND messageId = $id")
} }

View File

@ -63,37 +63,37 @@ public abstract class MetadataDao {
@Transaction @Transaction
public void setSeen(int profileId, Object o, boolean seen) { public void setSeen(int profileId, Object o, boolean seen) {
if (o instanceof Grade) { if (o instanceof Grade) {
if (add(new Metadata(profileId, TYPE_GRADE, ((Grade) o).getId(), seen, false, 0)) == -1) { if (add(new Metadata(profileId, TYPE_GRADE, ((Grade) o).getId(), seen, false)) == -1) {
updateSeen(profileId, TYPE_GRADE, ((Grade) o).getId(), seen); updateSeen(profileId, TYPE_GRADE, ((Grade) o).getId(), seen);
} }
} }
if (o instanceof Attendance) { if (o instanceof Attendance) {
if (add(new Metadata(profileId, TYPE_ATTENDANCE, ((Attendance) o).id, seen, false, 0)) == -1) { if (add(new Metadata(profileId, TYPE_ATTENDANCE, ((Attendance) o).getId(), seen, false)) == -1) {
updateSeen(profileId, TYPE_ATTENDANCE, ((Attendance) o).id, seen); updateSeen(profileId, TYPE_ATTENDANCE, ((Attendance) o).getId(), seen);
} }
} }
if (o instanceof Notice) { if (o instanceof Notice) {
if (add(new Metadata(profileId, TYPE_NOTICE, ((Notice) o).id, seen, false, 0)) == -1) { if (add(new Metadata(profileId, TYPE_NOTICE, ((Notice) o).getId(), seen, false)) == -1) {
updateSeen(profileId, TYPE_NOTICE, ((Notice) o).id, seen); updateSeen(profileId, TYPE_NOTICE, ((Notice) o).getId(), seen);
} }
} }
if (o instanceof Event) { if (o instanceof Event) {
if (add(new Metadata(profileId, ((Event) o).getType() == Event.TYPE_HOMEWORK ? TYPE_HOMEWORK : TYPE_EVENT, ((Event) o).getId(), seen, false, 0)) == -1) { if (add(new Metadata(profileId, ((Event) o).getType() == Event.TYPE_HOMEWORK ? TYPE_HOMEWORK : TYPE_EVENT, ((Event) o).getId(), seen, false)) == -1) {
updateSeen(profileId, ((Event) o).getType() == Event.TYPE_HOMEWORK ? TYPE_HOMEWORK : TYPE_EVENT, ((Event) o).getId(), seen); updateSeen(profileId, ((Event) o).getType() == Event.TYPE_HOMEWORK ? TYPE_HOMEWORK : TYPE_EVENT, ((Event) o).getId(), seen);
} }
} }
if (o instanceof LessonFull) { if (o instanceof LessonFull) {
if (add(new Metadata(profileId, TYPE_LESSON_CHANGE, ((LessonFull) o).getId(), seen, false, 0)) == -1) { if (add(new Metadata(profileId, TYPE_LESSON_CHANGE, ((LessonFull) o).getId(), seen, false)) == -1) {
updateSeen(profileId, TYPE_LESSON_CHANGE, ((LessonFull) o).getId(), seen); updateSeen(profileId, TYPE_LESSON_CHANGE, ((LessonFull) o).getId(), seen);
} }
} }
if (o instanceof Announcement) { if (o instanceof Announcement) {
if (add(new Metadata(profileId, TYPE_ANNOUNCEMENT, ((Announcement) o).id, seen, false, 0)) == -1) { if (add(new Metadata(profileId, TYPE_ANNOUNCEMENT, ((Announcement) o).getId(), seen, false)) == -1) {
updateSeen(profileId, TYPE_ANNOUNCEMENT, ((Announcement) o).id, seen); updateSeen(profileId, TYPE_ANNOUNCEMENT, ((Announcement) o).getId(), seen);
} }
} }
if (o instanceof Message) { if (o instanceof Message) {
if (add(new Metadata(profileId, TYPE_MESSAGE, ((Message) o).getId(), seen, false, 0)) == -1) { if (add(new Metadata(profileId, TYPE_MESSAGE, ((Message) o).getId(), seen, false)) == -1) {
updateSeen(profileId, TYPE_MESSAGE, ((Message) o).getId(), seen); updateSeen(profileId, TYPE_MESSAGE, ((Message) o).getId(), seen);
} }
} }
@ -102,37 +102,37 @@ public abstract class MetadataDao {
@Transaction @Transaction
public void setNotified(int profileId, Object o, boolean notified) { public void setNotified(int profileId, Object o, boolean notified) {
if (o instanceof Grade) { if (o instanceof Grade) {
if (add(new Metadata(profileId, TYPE_GRADE, ((Grade) o).getId(), false, notified, 0)) == -1) { if (add(new Metadata(profileId, TYPE_GRADE, ((Grade) o).getId(), false, notified)) == -1) {
updateNotified(profileId, TYPE_GRADE, ((Grade) o).getId(), notified); updateNotified(profileId, TYPE_GRADE, ((Grade) o).getId(), notified);
} }
} }
if (o instanceof Attendance) { if (o instanceof Attendance) {
if (add(new Metadata(profileId, TYPE_ATTENDANCE, ((Attendance) o).id, false, notified, 0)) == -1) { if (add(new Metadata(profileId, TYPE_ATTENDANCE, ((Attendance) o).getId(), false, notified)) == -1) {
updateNotified(profileId, TYPE_ATTENDANCE, ((Attendance) o).id, notified); updateNotified(profileId, TYPE_ATTENDANCE, ((Attendance) o).getId(), notified);
} }
} }
if (o instanceof Notice) { if (o instanceof Notice) {
if (add(new Metadata(profileId, TYPE_NOTICE, ((Notice) o).id, false, notified, 0)) == -1) { if (add(new Metadata(profileId, TYPE_NOTICE, ((Notice) o).getId(), false, notified)) == -1) {
updateNotified(profileId, TYPE_NOTICE, ((Notice) o).id, notified); updateNotified(profileId, TYPE_NOTICE, ((Notice) o).getId(), notified);
} }
} }
if (o instanceof Event) { if (o instanceof Event) {
if (add(new Metadata(profileId, ((Event) o).getType() == Event.TYPE_HOMEWORK ? TYPE_HOMEWORK : TYPE_EVENT, ((Event) o).getId(), false, notified, 0)) == -1) { if (add(new Metadata(profileId, ((Event) o).getType() == Event.TYPE_HOMEWORK ? TYPE_HOMEWORK : TYPE_EVENT, ((Event) o).getId(), false, notified)) == -1) {
updateNotified(profileId, ((Event) o).getType() == Event.TYPE_HOMEWORK ? TYPE_HOMEWORK : TYPE_EVENT, ((Event) o).getId(), notified); updateNotified(profileId, ((Event) o).getType() == Event.TYPE_HOMEWORK ? TYPE_HOMEWORK : TYPE_EVENT, ((Event) o).getId(), notified);
} }
} }
if (o instanceof LessonFull) { if (o instanceof LessonFull) {
if (add(new Metadata(profileId, TYPE_LESSON_CHANGE, ((LessonFull) o).getId(), false, notified, 0)) == -1) { if (add(new Metadata(profileId, TYPE_LESSON_CHANGE, ((LessonFull) o).getId(), false, notified)) == -1) {
updateNotified(profileId, TYPE_LESSON_CHANGE, ((LessonFull) o).getId(), notified); updateNotified(profileId, TYPE_LESSON_CHANGE, ((LessonFull) o).getId(), notified);
} }
} }
if (o instanceof Announcement) { if (o instanceof Announcement) {
if (add(new Metadata(profileId, TYPE_ANNOUNCEMENT, ((Announcement) o).id, false, notified, 0)) == -1) { if (add(new Metadata(profileId, TYPE_ANNOUNCEMENT, ((Announcement) o).getId(), false, notified)) == -1) {
updateNotified(profileId, TYPE_ANNOUNCEMENT, ((Announcement) o).id, notified); updateNotified(profileId, TYPE_ANNOUNCEMENT, ((Announcement) o).getId(), notified);
} }
} }
if (o instanceof Message) { if (o instanceof Message) {
if (add(new Metadata(profileId, TYPE_MESSAGE, ((Message) o).getId(), false, notified, 0)) == -1) { if (add(new Metadata(profileId, TYPE_MESSAGE, ((Message) o).getId(), false, notified)) == -1) {
updateNotified(profileId, TYPE_MESSAGE, ((Message) o).getId(), notified); updateNotified(profileId, TYPE_MESSAGE, ((Message) o).getId(), notified);
} }
} }
@ -141,7 +141,7 @@ public abstract class MetadataDao {
@Transaction @Transaction
public void setBoth(int profileId, Event o, boolean seen, boolean notified, long addedDate) { public void setBoth(int profileId, Event o, boolean seen, boolean notified, long addedDate) {
if (o != null) { if (o != null) {
if (add(new Metadata(profileId, o.getType() == Event.TYPE_HOMEWORK ? TYPE_HOMEWORK : TYPE_EVENT, o.getId(), seen, notified, addedDate)) == -1) { if (add(new Metadata(profileId, o.getType() == Event.TYPE_HOMEWORK ? TYPE_HOMEWORK : TYPE_EVENT, o.getId(), seen, notified)) == -1) {
updateSeen(profileId, o.getType() == Event.TYPE_HOMEWORK ? TYPE_HOMEWORK : TYPE_EVENT, o.getId(), seen); updateSeen(profileId, o.getType() == Event.TYPE_HOMEWORK ? TYPE_HOMEWORK : TYPE_EVENT, o.getId(), seen);
updateNotified(profileId, o.getType() == Event.TYPE_HOMEWORK ? TYPE_HOMEWORK : TYPE_EVENT, o.getId(), notified); updateNotified(profileId, o.getType() == Event.TYPE_HOMEWORK ? TYPE_HOMEWORK : TYPE_EVENT, o.getId(), notified);
} }

View File

@ -1,82 +0,0 @@
/*
* Copyright (c) Kacper Ziubryniewicz 2020-1-6
*/
package pl.szczodrzynski.edziennik.data.db.dao;
import androidx.lifecycle.LiveData;
import androidx.room.Dao;
import androidx.room.Insert;
import androidx.room.OnConflictStrategy;
import androidx.room.Query;
import androidx.room.RawQuery;
import androidx.sqlite.db.SimpleSQLiteQuery;
import androidx.sqlite.db.SupportSQLiteQuery;
import java.util.List;
import pl.szczodrzynski.edziennik.data.db.entity.Metadata;
import pl.szczodrzynski.edziennik.data.db.entity.Notice;
import pl.szczodrzynski.edziennik.data.db.full.NoticeFull;
import static pl.szczodrzynski.edziennik.data.db.entity.Metadata.TYPE_NOTICE;
@Dao
public abstract class NoticeDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
public abstract long add(Notice notice);
@Insert(onConflict = OnConflictStrategy.REPLACE)
public abstract void addAll(List<Notice> noticeList);
@Query("DELETE FROM notices WHERE profileId = :profileId")
public abstract void clear(int profileId);
@Query("DELETE FROM notices WHERE profileId = :profileId AND noticeSemester = :semester")
public abstract void clearForSemester(int profileId, int semester);
@RawQuery(observedEntities = {Notice.class})
abstract LiveData<List<NoticeFull>> getAll(SupportSQLiteQuery query);
public LiveData<List<NoticeFull>> getAll(int profileId, String filter) {
return getAll(new SimpleSQLiteQuery("SELECT \n" +
"*, \n" +
"teachers.teacherName || ' ' || teachers.teacherSurname AS teacherFullName\n" +
"FROM notices \n" +
"LEFT JOIN teachers USING(profileId, teacherId)\n" +
"LEFT JOIN metadata ON noticeId = thingId AND thingType = "+TYPE_NOTICE+" AND metadata.profileId = "+profileId+"\n" +
"WHERE notices.profileId = "+profileId+" AND "+filter+"\n" +
"ORDER BY addedDate DESC"));
}
public LiveData<List<NoticeFull>> getAll(int profileId) {
return getAll(profileId, "1");
}
public LiveData<List<NoticeFull>> getAllWhere(int profileId, String filter) {
return getAll(profileId, filter);
}
@RawQuery(observedEntities = {Notice.class, Metadata.class})
abstract List<NoticeFull> getAllNow(SupportSQLiteQuery query);
public List<NoticeFull> getAllNow(int profileId, String filter) {
return getAllNow(new SimpleSQLiteQuery("SELECT \n" +
"*, \n" +
"teachers.teacherName || ' ' || teachers.teacherSurname AS teacherFullName\n" +
"FROM notices \n" +
"LEFT JOIN teachers USING(profileId, teacherId)\n" +
"LEFT JOIN metadata ON noticeId = thingId AND thingType = "+TYPE_NOTICE+" AND metadata.profileId = "+profileId+"\n" +
"WHERE notices.profileId = "+profileId+" AND "+filter+"\n" +
"ORDER BY addedDate DESC"));
}
public List<NoticeFull> getNotNotifiedNow(int profileId) {
return getAllNow(profileId, "notified = 0");
}
@Query("SELECT " +
"*, " +
"teachers.teacherName || ' ' || teachers.teacherSurname AS teacherFullName " +
"FROM notices " +
"LEFT JOIN teachers USING(profileId, teacherId) " +
"LEFT JOIN metadata ON noticeId = thingId AND thingType = "+TYPE_NOTICE+" AND metadata.profileId = notices.profileId " +
"WHERE notified = 0 " +
"ORDER BY addedDate DESC")
public abstract List<NoticeFull> getNotNotifiedNow();
}

View File

@ -0,0 +1,72 @@
/*
* Copyright (c) Kuba Szczodrzyński 2020-4-25.
*/
package pl.szczodrzynski.edziennik.data.db.dao
import androidx.lifecycle.LiveData
import androidx.room.Dao
import androidx.room.Query
import androidx.room.RawQuery
import androidx.sqlite.db.SupportSQLiteQuery
import pl.szczodrzynski.edziennik.App
import pl.szczodrzynski.edziennik.annotation.SelectiveDao
import pl.szczodrzynski.edziennik.annotation.UpdateSelective
import pl.szczodrzynski.edziennik.data.db.AppDb
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
import pl.szczodrzynski.edziennik.data.db.entity.Notice
import pl.szczodrzynski.edziennik.data.db.full.NoticeFull
@Dao
@SelectiveDao(db = AppDb::class)
abstract class NoticeDao : BaseDao<Notice, NoticeFull> {
companion object {
private const val QUERY = """
SELECT
*,
teachers.teacherName ||" "|| teachers.teacherSurname AS teacherName
FROM notices
LEFT JOIN teachers USING(profileId, teacherId)
LEFT JOIN metadata ON noticeId = thingId AND thingType = ${Metadata.TYPE_NOTICE} AND metadata.profileId = notices.profileId
"""
private const val ORDER_BY = """ORDER BY addedDate DESC"""
}
private val selective by lazy { NoticeDaoSelective(App.db) }
@RawQuery(observedEntities = [Notice::class])
abstract override fun getRaw(query: SupportSQLiteQuery): LiveData<List<NoticeFull>>
@RawQuery(observedEntities = [Notice::class])
abstract override fun getOne(query: SupportSQLiteQuery): LiveData<NoticeFull?>
// SELECTIVE UPDATE
@UpdateSelective(primaryKeys = ["profileId", "noticeId"], skippedColumns = ["addedDate"])
override fun update(item: Notice) = selective.update(item)
override fun updateAll(items: List<Notice>) = selective.updateAll(items)
// CLEAR
@Query("DELETE FROM notices WHERE profileId = :profileId")
abstract override fun clear(profileId: Int)
// REMOVE NOT KEPT
@Query("DELETE FROM notices WHERE keep = 0")
abstract override fun removeNotKept()
// GET ALL - LIVE DATA
fun getAll(profileId: Int) =
getRaw("$QUERY WHERE notices.profileId = $profileId $ORDER_BY")
// GET ALL - NOW
fun getAllNow(profileId: Int) =
getRawNow("$QUERY WHERE notices.profileId = $profileId $ORDER_BY")
fun getNotNotifiedNow() =
getRawNow("$QUERY WHERE notified = 0 $ORDER_BY")
fun getNotNotifiedNow(profileId: Int) =
getRawNow("$QUERY WHERE notices.profileId = $profileId AND notified = 0 $ORDER_BY")
// GET ONE - NOW
fun getByIdNow(profileId: Int, id: Long) =
getOneNow("$QUERY WHERE notices.profileId = $profileId AND noticeId = $id")
@Query("UPDATE notices SET keep = 0 WHERE profileId = :profileId AND noticeSemester = :semester")
abstract fun dontKeepSemester(profileId: Int, semester: Int)
}

View File

@ -1,65 +1,74 @@
/* /*
* Copyright (c) Kacper Ziubryniewicz 2020-1-6 * Copyright (c) Kuba Szczodrzyński 2020-4-25.
*/ */
package pl.szczodrzynski.edziennik.data.db.dao package pl.szczodrzynski.edziennik.data.db.dao
import androidx.lifecycle.LiveData import androidx.lifecycle.LiveData
import androidx.room.Dao import androidx.room.Dao
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query import androidx.room.Query
import androidx.room.RawQuery
import androidx.sqlite.db.SupportSQLiteQuery
import pl.szczodrzynski.edziennik.App
import pl.szczodrzynski.edziennik.annotation.SelectiveDao
import pl.szczodrzynski.edziennik.annotation.UpdateSelective
import pl.szczodrzynski.edziennik.data.db.AppDb
import pl.szczodrzynski.edziennik.data.db.entity.Metadata import pl.szczodrzynski.edziennik.data.db.entity.Metadata
import pl.szczodrzynski.edziennik.data.db.entity.TeacherAbsence import pl.szczodrzynski.edziennik.data.db.entity.TeacherAbsence
import pl.szczodrzynski.edziennik.data.db.full.TeacherAbsenceFull import pl.szczodrzynski.edziennik.data.db.full.TeacherAbsenceFull
import pl.szczodrzynski.edziennik.utils.models.Date import pl.szczodrzynski.edziennik.utils.models.Date
@Dao @Dao
interface TeacherAbsenceDao { @SelectiveDao(db = AppDb::class)
abstract class TeacherAbsenceDao : BaseDao<TeacherAbsence, TeacherAbsenceFull> {
@Insert(onConflict = OnConflictStrategy.REPLACE) companion object {
fun add(teacherAbsence: TeacherAbsence) private const val QUERY = """
SELECT
@Insert(onConflict = OnConflictStrategy.REPLACE) *,
fun addAll(teacherAbsenceList: List<TeacherAbsence>) teachers.teacherName ||" "|| teachers.teacherSurname AS teacherName
@Query("SELECT * FROM teacherAbsence WHERE profileId = :profileId")
fun getAll(profileId: Int): List<TeacherAbsence>
@Query("SELECT *, teachers.teacherName || ' ' || teachers.teacherSurname as teacherFullName, " +
"metadata.seen, metadata.notified, metadata.addedDate FROM teacherAbsence " +
"LEFT JOIN teachers USING (profileId, teacherId) " +
"LEFT JOIN metadata ON teacherAbsenceId = thingId AND metadata.thingType = " + Metadata.TYPE_TEACHER_ABSENCE +
" AND metadata.profileId = :profileId WHERE teachers.profileId = :profileId")
fun getAllFullNow(profileId: Int): List<TeacherAbsenceFull>
@Query("SELECT *, teachers.teacherName || ' ' || teachers.teacherSurname as teacherFullName, " +
"metadata.seen, metadata.notified, metadata.addedDate FROM teacherAbsence " +
"LEFT JOIN teachers USING (profileId, teacherId) " +
"LEFT JOIN metadata ON teacherAbsenceId = thingId AND metadata.thingType = " + Metadata.TYPE_TEACHER_ABSENCE +
" AND metadata.profileId = :profileId WHERE teachers.profileId = :profileId " +
"AND :date BETWEEN teacherAbsenceDateFrom AND teacherAbsenceDateTo")
fun getAllByDateFull(profileId: Int, date: Date): LiveData<List<TeacherAbsenceFull>>
@Query("SELECT *, teachers.teacherName || ' ' || teachers.teacherSurname as teacherFullName, " +
"metadata.seen, metadata.notified, metadata.addedDate FROM teacherAbsence " +
"LEFT JOIN teachers USING (profileId, teacherId) " +
"LEFT JOIN metadata ON teacherAbsenceId = thingId AND metadata.thingType = " + Metadata.TYPE_TEACHER_ABSENCE +
" AND metadata.profileId = :profileId WHERE teachers.profileId = :profileId " +
"AND :date BETWEEN teacherAbsenceDateFrom AND teacherAbsenceDateTo")
fun getAllByDateNow(profileId: Int, date: Date): List<TeacherAbsenceFull>
@Query("""
SELECT *,
teachers.teacherName || ' ' || teachers.teacherSurname as teacherFullName
FROM teacherAbsence FROM teacherAbsence
LEFT JOIN teachers USING (profileId, teacherId) LEFT JOIN teachers USING(profileId, teacherId)
LEFT JOIN metadata ON teacherAbsenceId = thingId AND metadata.thingType = ${Metadata.TYPE_TEACHER_ABSENCE} LEFT JOIN metadata ON teacherAbsenceId = thingId AND thingType = ${Metadata.TYPE_TEACHER_ABSENCE} AND metadata.profileId = teacherAbsence.profileId
AND teachers.profileId = metadata.profileId WHERE metadata.notified = 0 """
ORDER BY addedDate DESC
""")
fun getNotNotifiedNow(): List<TeacherAbsenceFull>
private const val ORDER_BY = """ORDER BY teacherAbsenceDateFrom ASC"""
}
private val selective by lazy { TeacherAbsenceDaoSelective(App.db) }
@RawQuery(observedEntities = [TeacherAbsence::class])
abstract override fun getRaw(query: SupportSQLiteQuery): LiveData<List<TeacherAbsenceFull>>
@RawQuery(observedEntities = [TeacherAbsence::class])
abstract override fun getOne(query: SupportSQLiteQuery): LiveData<TeacherAbsenceFull?>
// SELECTIVE UPDATE
@UpdateSelective(primaryKeys = ["profileId", "teacherAbsenceId"], skippedColumns = ["addedDate"])
override fun update(item: TeacherAbsence) = selective.update(item)
override fun updateAll(items: List<TeacherAbsence>) = selective.updateAll(items)
// CLEAR
@Query("DELETE FROM teacherAbsence WHERE profileId = :profileId") @Query("DELETE FROM teacherAbsence WHERE profileId = :profileId")
fun clear(profileId: Int) abstract override fun clear(profileId: Int)
// REMOVE NOT KEPT
@Query("DELETE FROM teacherAbsence WHERE keep = 0")
abstract override fun removeNotKept()
// GET ALL - LIVE DATA
fun getAll(profileId: Int) =
getRaw("$QUERY WHERE teacherAbsence.profileId = $profileId $ORDER_BY")
fun getAllByDate(profileId: Int, date: Date) =
getRaw("$QUERY WHERE teacherAbsence.profileId = $profileId AND '${date.stringY_m_d}' BETWEEN teacherAbsenceDateFrom AND teacherAbsenceDateTo $ORDER_BY")
// GET ALL - NOW
fun getAllNow(profileId: Int) =
getRawNow("$QUERY WHERE teacherAbsence.profileId = $profileId $ORDER_BY")
fun getNotNotifiedNow() =
getRawNow("$QUERY WHERE notified = 0 $ORDER_BY")
fun getNotNotifiedNow(profileId: Int) =
getRawNow("$QUERY WHERE teacherAbsence.profileId = $profileId AND notified = 0 $ORDER_BY")
fun getAllByDateNow(profileId: Int, date: Date) =
getRawNow("$QUERY WHERE teacherAbsence.profileId = $profileId AND '${date.stringY_m_d}' BETWEEN teacherAbsenceDateFrom AND teacherAbsenceDateTo $ORDER_BY")
// GET ONE - NOW
fun getByIdNow(profileId: Int, id: Long) =
getOneNow("$QUERY WHERE teacherAbsence.profileId = $profileId AND teacherAbsenceId = $id")
} }

View File

@ -1,20 +1,25 @@
/* /*
* Copyright (c) Kacper Ziubryniewicz 2020-1-6 * Copyright (c) Kuba Szczodrzyński 2020-4-25.
*/ */
package pl.szczodrzynski.edziennik.data.db.dao package pl.szczodrzynski.edziennik.data.db.dao
import androidx.lifecycle.LiveData import androidx.lifecycle.LiveData
import androidx.room.* import androidx.room.Dao
import androidx.sqlite.db.SimpleSQLiteQuery import androidx.room.Query
import androidx.room.RawQuery
import androidx.sqlite.db.SupportSQLiteQuery import androidx.sqlite.db.SupportSQLiteQuery
import pl.szczodrzynski.edziennik.App
import pl.szczodrzynski.edziennik.annotation.SelectiveDao
import pl.szczodrzynski.edziennik.annotation.UpdateSelective
import pl.szczodrzynski.edziennik.data.db.AppDb
import pl.szczodrzynski.edziennik.data.db.entity.Lesson import pl.szczodrzynski.edziennik.data.db.entity.Lesson
import pl.szczodrzynski.edziennik.data.db.entity.Metadata import pl.szczodrzynski.edziennik.data.db.entity.Metadata
import pl.szczodrzynski.edziennik.data.db.full.LessonFull import pl.szczodrzynski.edziennik.data.db.full.LessonFull
import pl.szczodrzynski.edziennik.utils.models.Date import pl.szczodrzynski.edziennik.utils.models.Date
@Dao @Dao
interface TimetableDao { @SelectiveDao(db = AppDb::class)
abstract class TimetableDao : BaseDao<Lesson, LessonFull> {
companion object { companion object {
private const val QUERY = """ private const val QUERY = """
SELECT SELECT
@ -25,7 +30,7 @@ interface TimetableDao {
oldS.subjectLongName AS oldSubjectName, oldS.subjectLongName AS oldSubjectName,
oldT.teacherName ||" "|| oldT.teacherSurname AS oldTeacherName, oldT.teacherName ||" "|| oldT.teacherSurname AS oldTeacherName,
oldG.teamName AS oldTeamName, oldG.teamName AS oldTeamName,
metadata.seen, metadata.notified, metadata.addedDate metadata.seen, metadata.notified
FROM timetable FROM timetable
LEFT JOIN subjects USING(profileId, subjectId) LEFT JOIN subjects USING(profileId, subjectId)
LEFT JOIN teachers USING(profileId, teacherId) LEFT JOIN teachers USING(profileId, teacherId)
@ -35,111 +40,77 @@ interface TimetableDao {
LEFT JOIN teams AS oldG ON timetable.profileId = oldG.profileId AND timetable.oldTeamId = oldG.teamId LEFT JOIN teams AS oldG ON timetable.profileId = oldG.profileId AND timetable.oldTeamId = oldG.teamId
LEFT JOIN metadata ON id = thingId AND thingType = ${Metadata.TYPE_LESSON_CHANGE} AND metadata.profileId = timetable.profileId LEFT JOIN metadata ON id = thingId AND thingType = ${Metadata.TYPE_LESSON_CHANGE} AND metadata.profileId = timetable.profileId
""" """
private const val ORDER_BY = """ORDER BY profileId, id, type"""
private const val IS_CHANGED = """type != -1 AND type != 0"""
} }
@Insert(onConflict = OnConflictStrategy.REPLACE) private val selective by lazy { TimetableDaoSelective(App.db) }
operator fun plusAssign(lessonList: List<Lesson>)
@Query("DELETE FROM timetable WHERE profileId = :profileId")
fun clear(profileId: Int)
@Query("DELETE FROM timetable WHERE profileId = :profileId AND type != -1 AND ((type != 3 AND date >= :dateFrom) OR ((type = 3 OR type = 1) AND oldDate >= :dateFrom))")
fun clearFromDate(profileId: Int, dateFrom: Date)
@Query("DELETE FROM timetable WHERE profileId = :profileId AND type != -1 AND ((type != 3 AND date <= :dateTo) OR ((type = 3 OR type = 1) AND oldDate <= :dateTo))")
fun clearToDate(profileId: Int, dateTo: Date)
@Query("DELETE FROM timetable WHERE profileId = :profileId AND type != -1 AND ((type != 3 AND date >= :dateFrom AND date <= :dateTo) OR ((type = 3 OR type = 1) AND oldDate >= :dateFrom AND oldDate <= :dateTo))")
fun clearBetweenDates(profileId: Int, dateFrom: Date, dateTo: Date)
@RawQuery(observedEntities = [Lesson::class]) @RawQuery(observedEntities = [Lesson::class])
fun getRaw(query: SupportSQLiteQuery): LiveData<List<LessonFull>> abstract override fun getRaw(query: SupportSQLiteQuery): LiveData<List<LessonFull>>
@RawQuery(observedEntities = [Lesson::class])
abstract override fun getOne(query: SupportSQLiteQuery): LiveData<LessonFull?>
@Query(""" // SELECTIVE UPDATE
$QUERY @UpdateSelective(primaryKeys = ["profileId", "id"], skippedColumns = ["addedDate"])
WHERE timetable.profileId = :profileId AND type != -1 AND type != 0 override fun update(item: Lesson) = selective.update(item)
ORDER BY id, type override fun updateAll(items: List<Lesson>) = selective.updateAll(items)
""")
fun getAllChangesNow(profileId: Int): List<LessonFull>
@Query(""" // CLEAR
$QUERY @Query("DELETE FROM timetable WHERE profileId = :profileId")
WHERE timetable.profileId = :profileId AND type != -1 AND type != 0 AND ((type != 3 AND date = :date) OR ((type = 3 OR type = 1) AND oldDate = :date)) abstract override fun clear(profileId: Int)
ORDER BY id, type // REMOVE NOT KEPT
""") @Query("DELETE FROM timetable WHERE keep = 0")
fun getChangesForDateNow(profileId: Int, date: Date): List<LessonFull> abstract override fun removeNotKept()
fun getForDate(profileId: Int, date: Date) = getRaw(SimpleSQLiteQuery(""" // GET ALL - LIVE DATA
$QUERY fun getAll(profileId: Int) =
WHERE timetable.profileId = $profileId AND ((type != 3 AND date = "${date.stringY_m_d}") OR ((type = 3 OR type = 1) AND oldDate = "${date.stringY_m_d}")) getRaw("$QUERY WHERE timetable.profileId = $profileId $ORDER_BY")
ORDER BY id, type fun getAllForDate(profileId: Int, date: Date) =
""")) getRaw("$QUERY WHERE timetable.profileId = $profileId AND ((type != 3 AND date = '${date.stringY_m_d}') OR ((type = 3 OR type = 1) AND oldDate = '${date.stringY_m_d}')) $ORDER_BY")
fun getNextWithSubject(profileId: Int, date: Date, subjectId: Long) =
getOne("$QUERY " +
"WHERE timetable.profileId = $profileId " +
"AND ((type != 3 AND date > '${date.stringY_m_d}') OR ((type = 3 OR type = 1) AND oldDate > '${date.stringY_m_d}')) " +
"AND timetable.subjectId = $subjectId " +
"LIMIT 1")
fun getNextWithSubjectAndTeam(profileId: Int, date: Date, subjectId: Long, teamId: Long) =
getOne("$QUERY " +
"WHERE timetable.profileId = $profileId " +
"AND ((type != 3 AND date > '${date.stringY_m_d}') OR ((type = 3 OR type = 1) AND oldDate > '${date.stringY_m_d}')) " +
"AND timetable.subjectId = $subjectId " +
"AND timetable.teamId = $teamId " +
"LIMIT 1")
fun getBetweenDates(dateFrom: Date, dateTo: Date) =
getRaw("$QUERY WHERE (type != 3 AND date >= '${dateFrom.stringY_m_d}' AND date <= '${dateTo.stringY_m_d}') OR ((type = 3 OR type = 1) AND oldDate >= '${dateFrom.stringY_m_d}' AND oldDate <= '${dateTo.stringY_m_d}') $ORDER_BY")
@Query(""" // GET ALL - NOW
$QUERY fun getAllNow(profileId: Int) =
WHERE timetable.profileId = :profileId AND ((type != 3 AND date = :date) OR ((type = 3 OR type = 1) AND oldDate = :date)) getRawNow("$QUERY WHERE timetable.profileId = $profileId $ORDER_BY")
ORDER BY id, type fun getNotNotifiedNow() =
""") getRawNow("$QUERY WHERE notified = 0 AND timetable.type NOT IN (${Lesson.TYPE_NORMAL}, ${Lesson.TYPE_NO_LESSONS}, ${Lesson.TYPE_SHIFTED_SOURCE}) $ORDER_BY")
fun getForDateNow(profileId: Int, date: Date): List<LessonFull> fun getNotNotifiedNow(profileId: Int) =
getRawNow("$QUERY WHERE timetable.profileId = $profileId AND notified = 0 AND timetable.type NOT IN (${Lesson.TYPE_NORMAL}, ${Lesson.TYPE_NO_LESSONS}, ${Lesson.TYPE_SHIFTED_SOURCE}) $ORDER_BY")
fun getAllForDateNow(profileId: Int, date: Date) =
getRawNow("$QUERY WHERE timetable.profileId = $profileId AND ((type != 3 AND date = '${date.stringY_m_d}') OR ((type = 3 OR type = 1) AND oldDate = '${date.stringY_m_d}')) $ORDER_BY")
fun getChangesNow(profileId: Int) =
getRawNow("$QUERY WHERE timetable.profileId = $profileId AND $IS_CHANGED $ORDER_BY")
fun getChangesForDateNow(profileId: Int, date: Date) =
getRawNow("$QUERY WHERE timetable.profileId = $profileId AND $IS_CHANGED AND ((type != 3 AND date = '${date.stringY_m_d}') OR ((type = 3 OR type = 1) AND oldDate = '${date.stringY_m_d}')) $ORDER_BY")
fun getBetweenDatesNow(dateFrom: Date, dateTo: Date) =
getRawNow("$QUERY WHERE (type != 3 AND date >= '${dateFrom.stringY_m_d}' AND date <= '${dateTo.stringY_m_d}') OR ((type = 3 OR type = 1) AND oldDate >= '${dateFrom.stringY_m_d}' AND oldDate <= '${dateTo.stringY_m_d}') $ORDER_BY")
@Query(""" // GET ONE - NOW
$QUERY fun getByIdNow(profileId: Int, id: Long) =
WHERE timetable.profileId = :profileId AND ((type != 3 AND date > :today) OR ((type = 3 OR type = 1) AND oldDate > :today)) AND timetable.subjectId = :subjectId getOneNow("$QUERY WHERE timetable.profileId = $profileId AND timetable.id = $id")
ORDER BY id, type
LIMIT 1
""")
fun getNextWithSubject(profileId: Int, today: Date, subjectId: Long): LiveData<LessonFull?>
@Query(""" @Query("UPDATE timetable SET keep = 0 WHERE profileId = :profileId AND type != -1 AND ((type != 3 AND date >= :dateFrom) OR ((type = 3 OR type = 1) AND oldDate >= :dateFrom))")
$QUERY abstract fun dontKeepFromDate(profileId: Int, dateFrom: Date)
WHERE timetable.profileId = :profileId AND ((type != 3 AND date > :today) OR ((type = 3 OR type = 1) AND oldDate > :today)) AND timetable.subjectId = :subjectId AND timetable.teamId = :teamId
ORDER BY id, type
LIMIT 1
""")
fun getNextWithSubjectAndTeam(profileId: Int, today: Date, subjectId: Long, teamId: Long): LiveData<LessonFull?>
@Query(""" @Query("UPDATE timetable SET keep = 0 WHERE profileId = :profileId AND type != -1 AND ((type != 3 AND date <= :dateTo) OR ((type = 3 OR type = 1) AND oldDate <= :dateTo))")
$QUERY abstract fun dontKeepToDate(profileId: Int, dateTo: Date)
WHERE (type != 3 AND date >= :dateFrom AND date <= :dateTo) OR ((type = 3 OR type = 1) AND oldDate >= :dateFrom AND oldDate <= :dateTo)
ORDER BY profileId, id, type
""")
fun getBetweenDatesNow(dateFrom: Date, dateTo: Date): List<LessonFull>
@Query(""" @Query("UPDATE timetable SET keep = 0 WHERE profileId = :profileId AND type != -1 AND ((type != 3 AND date >= :dateFrom AND date <= :dateTo) OR ((type = 3 OR type = 1) AND oldDate >= :dateFrom AND oldDate <= :dateTo))")
$QUERY abstract fun dontKeepBetweenDates(profileId: Int, dateFrom: Date, dateTo: Date)
WHERE (type != 3 AND date >= :dateFrom AND date <= :dateTo) OR ((type = 3 OR type = 1) AND oldDate >= :dateFrom AND oldDate <= :dateTo)
ORDER BY profileId, id, type
""")
fun getBetweenDates(dateFrom: Date, dateTo: Date): LiveData<List<LessonFull>>
@Query("""
$QUERY
WHERE timetable.profileId = :profileId AND timetable.id = :lessonId
ORDER BY id, type
""")
fun getByIdNow(profileId: Int, lessonId: Long): LessonFull?
@Query("""
$QUERY
WHERE timetable.profileId = :profileId AND timetable.type NOT IN (${Lesson.TYPE_NORMAL}, ${Lesson.TYPE_NO_LESSONS}, ${Lesson.TYPE_SHIFTED_SOURCE}) AND metadata.notified = 0
""")
fun getNotNotifiedNow(profileId: Int): List<LessonFull>
@Query("""
SELECT
timetable.*,
subjects.subjectLongName AS subjectName,
teachers.teacherName ||" "|| teachers.teacherSurname AS teacherName,
oldS.subjectLongName AS oldSubjectName,
oldT.teacherName ||" "|| oldT.teacherSurname AS oldTeacherName,
metadata.seen, metadata.notified, metadata.addedDate
FROM timetable
LEFT JOIN subjects USING(profileId, subjectId)
LEFT JOIN teachers USING(profileId, teacherId)
LEFT JOIN subjects AS oldS ON timetable.profileId = oldS.profileId AND timetable.oldSubjectId = oldS.subjectId
LEFT JOIN teachers AS oldT ON timetable.profileId = oldT.profileId AND timetable.oldTeacherId = oldT.teacherId
LEFT JOIN metadata ON id = thingId AND thingType = ${Metadata.TYPE_LESSON_CHANGE} AND metadata.profileId = timetable.profileId
WHERE timetable.type NOT IN (${Lesson.TYPE_NORMAL}, ${Lesson.TYPE_NO_LESSONS}, ${Lesson.TYPE_SHIFTED_SOURCE}) AND metadata.notified = 0
""")
fun getNotNotifiedNow(): List<LessonFull>
} }

View File

@ -1,58 +0,0 @@
/*
* Copyright (c) Kacper Ziubryniewicz 2020-1-6
*/
package pl.szczodrzynski.edziennik.data.db.entity;
import androidx.annotation.Nullable;
import androidx.room.ColumnInfo;
import androidx.room.Entity;
import androidx.room.Ignore;
import androidx.room.Index;
import pl.szczodrzynski.edziennik.utils.models.Date;
@Entity(tableName = "announcements",
primaryKeys = {"profileId", "announcementId"},
indices = {@Index(value = {"profileId"})})
public class Announcement {
public int profileId;
@ColumnInfo(name = "announcementId")
public long id;
@ColumnInfo(name = "announcementSubject")
public String subject;
@Nullable
@ColumnInfo(name = "announcementText")
public String text;
@Nullable
@ColumnInfo(name = "announcementStartDate")
public Date startDate;
@Nullable
@ColumnInfo(name = "announcementEndDate")
public Date endDate;
public long teacherId;
@Nullable
@ColumnInfo(name = "announcementIdString")
public String idString;
@Ignore
public Announcement() {}
public Announcement(int profileId, long id, String subject, String text, @Nullable Date startDate, @Nullable Date endDate, long teacherId, @Nullable String idString) {
this.profileId = profileId;
this.id = id;
this.subject = subject;
this.text = text;
this.startDate = startDate;
this.endDate = endDate;
this.teacherId = teacherId;
this.idString = idString;
}
}

View File

@ -0,0 +1,40 @@
/*
* Copyright (c) Kuba Szczodrzyński 2020-4-24.
*/
package pl.szczodrzynski.edziennik.data.db.entity
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.Ignore
import androidx.room.Index
import pl.szczodrzynski.edziennik.utils.models.Date
@Entity(tableName = "announcements",
primaryKeys = ["profileId", "announcementId"],
indices = [
Index(value = ["profileId"])
])
open class Announcement(
val profileId: Int,
@ColumnInfo(name = "announcementId")
var id: Long,
@ColumnInfo(name = "announcementSubject")
var subject: String,
@ColumnInfo(name = "announcementText")
var text: String?,
@ColumnInfo(name = "announcementStartDate")
var startDate: Date?,
@ColumnInfo(name = "announcementEndDate")
var endDate: Date?,
var teacherId: Long,
var addedDate: Long = System.currentTimeMillis()
) : Keepable() {
@ColumnInfo(name = "announcementIdString")
var idString: String? = null
@Ignore
var showAsUnseen: Boolean? = null
}

View File

@ -1,65 +0,0 @@
/*
* Copyright (c) Kacper Ziubryniewicz 2020-1-6
*/
package pl.szczodrzynski.edziennik.data.db.entity;
import androidx.annotation.NonNull;
import androidx.room.ColumnInfo;
import androidx.room.Entity;
import androidx.room.Ignore;
import androidx.room.Index;
import pl.szczodrzynski.edziennik.utils.models.Date;
import pl.szczodrzynski.edziennik.utils.models.Time;
@Entity(tableName = "attendances",
primaryKeys = {"profileId", "attendanceId", "attendanceLessonDate", "attendanceStartTime"},
indices = {@Index(value = {"profileId"})})
public class Attendance {
public int profileId;
@ColumnInfo(name = "attendanceId")
public long id;
@NonNull
@ColumnInfo(name = "attendanceLessonDate")
public Date lessonDate;
@NonNull
@ColumnInfo(name = "attendanceStartTime")
public Time startTime;
@ColumnInfo(name = "attendanceLessonTopic")
public String lessonTopic;
@ColumnInfo(name = "attendanceSemester")
public int semester;
public static final int TYPE_PRESENT = 0;
public static final int TYPE_ABSENT = 1;
public static final int TYPE_ABSENT_EXCUSED = 2;
public static final int TYPE_RELEASED = 3;
public static final int TYPE_BELATED = 4;
public static final int TYPE_BELATED_EXCUSED = 5;
public static final int TYPE_CUSTOM = 6;
public static final int TYPE_DAY_FREE = 7;
@ColumnInfo(name = "attendanceType")
public int type = TYPE_PRESENT;
public long teacherId;
public long subjectId;
@Ignore
public Attendance() {
this(-1, -1, -1, -1, 0, "", Date.getToday(), Time.getNow(), TYPE_PRESENT);
}
public Attendance(int profileId, long id, long teacherId, long subjectId, int semester, String lessonTopic, Date lessonDate, Time startTime, int type) {
this.profileId = profileId;
this.id = id;
this.teacherId = teacherId;
this.subjectId = subjectId;
this.semester = semester;
this.lessonTopic = lessonTopic;
this.lessonDate = lessonDate;
this.startTime = startTime;
this.type = type;
}
}

View File

@ -0,0 +1,68 @@
/*
* Copyright (c) Kuba Szczodrzyński 2020-4-24.
*/
package pl.szczodrzynski.edziennik.data.db.entity
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.Ignore
import androidx.room.Index
import pl.szczodrzynski.edziennik.utils.models.Date
import pl.szczodrzynski.edziennik.utils.models.Time
@Entity(tableName = "attendances",
primaryKeys = ["profileId", "attendanceId"],
indices = [
Index(value = ["profileId"])
])
open class Attendance(
val profileId: Int,
@ColumnInfo(name = "attendanceId")
var id: Long,
/** Base type ID used to count attendance stats */
@ColumnInfo(name = "attendanceBaseType")
var baseType: Int,
/** A full type name coming from the e-register */
@ColumnInfo(name = "attendanceTypeName")
var typeName: String,
/** A short name to display by default, might be different for non-standard types */
@ColumnInfo(name = "attendanceTypeShort")
val typeShort: String,
/** A short name that the e-register would display */
@ColumnInfo(name = "attendanceTypeSymbol")
var typeSymbol: String,
/** A color that the e-register would display, null falls back to app's default */
@ColumnInfo(name = "attendanceTypeColor")
var typeColor: Int?,
@ColumnInfo(name = "attendanceDate")
var date: Date,
@ColumnInfo(name = "attendanceTime")
var startTime: Time?,
@ColumnInfo(name = "attendanceSemester")
var semester: Int,
var teacherId: Long,
var subjectId: Long,
var addedDate: Long = System.currentTimeMillis()
) : Keepable() {
companion object {
const val TYPE_UNKNOWN = -1
const val TYPE_PRESENT = 0
const val TYPE_PRESENT_CUSTOM = 10 // count as presence AND show in the list
const val TYPE_ABSENT = 1
const val TYPE_ABSENT_EXCUSED = 2
const val TYPE_RELEASED = 3
const val TYPE_BELATED = 4
const val TYPE_BELATED_EXCUSED = 5
const val TYPE_DAY_FREE = 6
}
@ColumnInfo(name = "attendanceLessonTopic")
var lessonTopic: String? = null
@ColumnInfo(name = "attendanceLessonNumber")
var lessonNumber: Int? = null
@Ignore
var showAsUnseen = false
}

View File

@ -9,15 +9,16 @@ import androidx.room.Entity
@Entity(tableName = "attendanceTypes", @Entity(tableName = "attendanceTypes",
primaryKeys = ["profileId", "id"]) primaryKeys = ["profileId", "id"])
data class AttendanceType ( data class AttendanceType (
val profileId: Int, val profileId: Int,
val id: Long, val id: Long,
/** Base type ID used to count attendance stats */
val name: String, val baseType: Int,
/** A full type name coming from the e-register */
val type: Int, val typeName: String,
/** A short name to display by default, might be different for non-standard types */
val color: Int val typeShort: String,
/** A short name that the e-register would display */
val typeSymbol: String,
/** A color that the e-register would display, null falls back to app's default */
val typeColor: Int?
) )

View File

@ -41,7 +41,8 @@ open class Event(
var teacherId: Long, var teacherId: Long,
var subjectId: Long, var subjectId: Long,
var teamId: Long var teamId: Long,
var addedDate: Long = System.currentTimeMillis()
) : Keepable() { ) : Keepable() {
companion object { companion object {
const val TYPE_UNDEFINED = -2L const val TYPE_UNDEFINED = -2L

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) Kacper Ziubryniewicz 2020-1-6 * Copyright (c) Kuba Szczodrzyński 2020-4-24.
*/ */
package pl.szczodrzynski.edziennik.data.db.entity package pl.szczodrzynski.edziennik.data.db.entity
@ -8,23 +8,11 @@ import androidx.room.Entity
import androidx.room.Ignore import androidx.room.Ignore
import androidx.room.Index import androidx.room.Index
/*public Grade(int profileId, long id, String category, int color, String description, String name, float value, float weight, int semester, long teacherId, long subjectId) {
this.profileId = profileId;
this.id = id;
this.category = category;
this.color = color;
this.description = description;
this.name = name;
this.value = value;
this.weight = weight;
this.semester = semester;
this.teacherId = teacherId;
this.subjectId = subjectId;
}*/
@Entity(tableName = "grades", @Entity(tableName = "grades",
primaryKeys = ["profileId", "gradeId"], primaryKeys = ["profileId", "gradeId"],
indices = [Index(value = ["profileId"])]) indices = [
Index(value = ["profileId"])
])
open class Grade( open class Grade(
val profileId: Int, val profileId: Int,
@ColumnInfo(name = "gradeId") @ColumnInfo(name = "gradeId")
@ -40,6 +28,7 @@ open class Grade(
var weight: Float, var weight: Float,
@ColumnInfo(name = "gradeColor") @ColumnInfo(name = "gradeColor")
var color: Int, var color: Int,
@ColumnInfo(name = "gradeCategory") @ColumnInfo(name = "gradeCategory")
var category: String?, var category: String?,
@ColumnInfo(name = "gradeDescription") @ColumnInfo(name = "gradeDescription")
@ -50,8 +39,9 @@ open class Grade(
@ColumnInfo(name = "gradeSemester") @ColumnInfo(name = "gradeSemester")
val semester: Int, val semester: Int,
val teacherId: Long, val teacherId: Long,
val subjectId: Long val subjectId: Long,
) { var addedDate: Long = System.currentTimeMillis()
) : Keepable() {
companion object { companion object {
const val TYPE_NORMAL = 0 const val TYPE_NORMAL = 0
const val TYPE_SEMESTER1_PROPOSED = 1 const val TYPE_SEMESTER1_PROPOSED = 1

View File

@ -1,7 +1,6 @@
/* /*
* Copyright (c) Kacper Ziubryniewicz 2020-1-6 * Copyright (c) Kuba Szczodrzyński 2020-4-25.
*/ */
package pl.szczodrzynski.edziennik.data.db.entity package pl.szczodrzynski.edziennik.data.db.entity
import androidx.room.Entity import androidx.room.Entity
@ -11,12 +10,15 @@ import pl.szczodrzynski.edziennik.utils.models.Date
import pl.szczodrzynski.edziennik.utils.models.Time import pl.szczodrzynski.edziennik.utils.models.Time
@Entity(tableName = "timetable", @Entity(tableName = "timetable",
primaryKeys = ["profileId", "id"],
indices = [ indices = [
Index(value = ["profileId", "type", "date"]), Index(value = ["profileId", "type", "date"]),
Index(value = ["profileId", "type", "oldDate"]) Index(value = ["profileId", "type", "oldDate"])
], ])
primaryKeys = ["profileId", "id"]) open class Lesson(
open class Lesson(val profileId: Int, var id: Long) { val profileId: Int,
var id: Long
) : Keepable() {
companion object { companion object {
const val TYPE_NO_LESSONS = -1 const val TYPE_NO_LESSONS = -1
const val TYPE_NORMAL = 0 const val TYPE_NORMAL = 0

View File

@ -1,35 +0,0 @@
/*
* Copyright (c) Kacper Ziubryniewicz 2020-1-6
*/
package pl.szczodrzynski.edziennik.data.db.entity;
import androidx.annotation.NonNull;
import androidx.room.ColumnInfo;
import androidx.room.Entity;
import androidx.room.Ignore;
import pl.szczodrzynski.edziennik.utils.models.Date;
@Entity(tableName = "luckyNumbers",
primaryKeys = {"profileId", "luckyNumberDate"})
public class LuckyNumber {
public int profileId;
@NonNull
@ColumnInfo(name = "luckyNumberDate", typeAffinity = 3)
public Date date;
@ColumnInfo(name = "luckyNumber")
public int number;
public LuckyNumber(int profileId, @NonNull Date date, int number) {
this.profileId = profileId;
this.date = date;
this.number = number;
}
@Ignore
public LuckyNumber() {
this.date = Date.getToday();
}
}

Some files were not shown because too many files have changed in this diff Show More