From 875efcff7e303decfad1a237a77c89934d333ffd Mon Sep 17 00:00:00 2001
From: Kacper Ziubryniewicz <kapi2289@gmail.com>
Date: Sun, 24 Nov 2019 12:08:14 +0100
Subject: [PATCH] [APIv2/Timetable] Fix ID in lessons.

---
 .../pl/szczodrzynski/edziennik/Extensions.kt  | 14 ++--
 .../szczodrzynski/edziennik/MainActivity.kt   |  4 +-
 .../data/web/IdziennikWebTimetable.kt         |  5 +-
 .../v2/librus/data/api/LibrusApiTimetables.kt |  5 +-
 .../data/api/MobidziennikApiTimetable.kt      |  5 +-
 .../v2/vulcan/data/api/VulcanApiTimetable.kt  |  8 +--
 .../data/db/modules/timetable/Lesson.kt       | 69 ++++++++++++++++++-
 .../data/db/modules/timetable/LessonFull.kt   | 15 ----
 .../edziennik/utils/models/Date.java          |  8 +++
 .../edziennik/utils/models/Time.java          | 16 +++--
 10 files changed, 108 insertions(+), 41 deletions(-)

diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/Extensions.kt b/app/src/main/java/pl/szczodrzynski/edziennik/Extensions.kt
index 8a014e1c..97a8a6f4 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/Extensions.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/Extensions.kt
@@ -418,15 +418,15 @@ fun TextView.setText(@StringRes resid: Int, vararg formatArgs: Any) {
     text = context.getString(resid, *formatArgs)
 }
 
-fun JsonObject(vararg properties: Pair<String, Any>): JsonObject {
+fun JsonObject(vararg properties: Pair<String, Any?>): JsonObject {
     return JsonObject().apply {
         for (property in properties) {
             when (property.second) {
-                is JsonElement -> add(property.first, property.second as JsonElement)
-                is String -> addProperty(property.first, property.second as String)
-                is Char -> addProperty(property.first, property.second as Char)
-                is Number -> addProperty(property.first, property.second as Number)
-                is Boolean -> addProperty(property.first, property.second as Boolean)
+                is JsonElement -> add(property.first, property.second as JsonElement?)
+                is String -> addProperty(property.first, property.second as String?)
+                is Char -> addProperty(property.first, property.second as Char?)
+                is Number -> addProperty(property.first, property.second as Number?)
+                is Boolean -> addProperty(property.first, property.second as Boolean?)
             }
         }
     }
@@ -502,4 +502,4 @@ fun View.findParentById(targetId: Int): View? {
         return viewParent.findParentById(targetId)
     }
     return null
-}
\ No newline at end of file
+}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/MainActivity.kt b/app/src/main/java/pl/szczodrzynski/edziennik/MainActivity.kt
index 02f45192..46e70e04 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/MainActivity.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/MainActivity.kt
@@ -538,9 +538,7 @@ class MainActivity : AppCompatActivity() {
             else -> 0
         }
         val arguments = when (navTargetId) {
-            DRAWER_ITEM_TIMETABLE -> JsonObject().apply {
-                addProperty("weekStart", TimetableFragment.pageSelection?.weekStart?.stringY_m_d)
-            }
+            DRAWER_ITEM_TIMETABLE -> JsonObject("weekStart" to TimetableFragment.pageSelection?.weekStart?.stringY_m_d)
             else -> null
         }
         EdziennikTask.syncProfile(
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/idziennik/data/web/IdziennikWebTimetable.kt b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/idziennik/data/web/IdziennikWebTimetable.kt
index b7f93607..e2250c38 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/idziennik/data/web/IdziennikWebTimetable.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/idziennik/data/web/IdziennikWebTimetable.kt
@@ -91,10 +91,9 @@ class IdziennikWebTimetable(override val data: DataIdziennik,
                 val lessonDate = weekStart.clone().stepForward(0, 0, weekDay)
                 val classroom = lesson.getString("NazwaSali")
 
-                val id = lessonDate.combineWith(lessonRange.startTime) / 6L * 10L + (lesson.hashCode() and 0xFFFF)
                 val type = lesson.getInt("TypZastepstwa") ?: -1
 
-                val lessonObject = Lesson(profileId, id)
+                val lessonObject = Lesson(profileId, -1)
 
                 when (type) {
                     1, 2, 3, 4, 5 -> {
@@ -150,6 +149,8 @@ class IdziennikWebTimetable(override val data: DataIdziennik,
                     }
                 }
 
+                lessonObject.id = lessonObject.buildId()
+
                 dates.add(lessonDate.value)
                 lessons.add(lessonObject)
 
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/librus/data/api/LibrusApiTimetables.kt b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/librus/data/api/LibrusApiTimetables.kt
index 22813718..44ba9288 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/librus/data/api/LibrusApiTimetables.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/librus/data/api/LibrusApiTimetables.kt
@@ -88,8 +88,7 @@ class LibrusApiTimetables(override val data: DataLibrus,
         val virtualClassId = lesson.getJsonObject("VirtualClass")?.getLong("Id")
         val teamId = lesson.getJsonObject("Class")?.getLong("Id") ?: virtualClassId
 
-        val id = lessonDate.combineWith(startTime) / 6L * 10L + (lesson.hashCode() and 0xFFFF)
-        val lessonObject = Lesson(profileId, id)
+        val lessonObject = Lesson(profileId, -1)
 
         if (isSubstitution && isCancelled) {
             // shifted lesson - source
@@ -184,6 +183,8 @@ class LibrusApiTimetables(override val data: DataLibrus,
             }
         }
 
+        lessonObject.id = lessonObject.buildId()
+
         val seen = profile.empty || lessonDate < Date.getToday()
 
         if (lessonObject.type != Lesson.TYPE_NORMAL) {
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/mobidziennik/data/api/MobidziennikApiTimetable.kt b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/mobidziennik/data/api/MobidziennikApiTimetable.kt
index bd970eb3..e6cd4e6b 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/mobidziennik/data/api/MobidziennikApiTimetable.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/mobidziennik/data/api/MobidziennikApiTimetable.kt
@@ -32,7 +32,6 @@ class MobidziennikApiTimetable(val data: DataMobidziennik, rows: List<String>) {
             val date = Date.fromYmd(lesson[2])
             val startTime = Time.fromYmdHm(lesson[3])
             val endTime = Time.fromYmdHm(lesson[4])
-            val id = date.combineWith(startTime) / 6L * 10L + (lesson.joinToString("|").hashCode() and 0xFFFF)
 
             dataDays.remove(date.value)
 
@@ -41,7 +40,7 @@ class MobidziennikApiTimetable(val data: DataMobidziennik, rows: List<String>) {
             val teamId = data.teamList.singleOrNull { it.name == lesson[8]+lesson[9] }?.id ?: -1
             val classroom = lesson[11]
 
-            Lesson(data.profileId, id).also {
+            Lesson(data.profileId, -1).also {
                 when (lesson[1]) {
                     "plan_lekcji", "lekcja" -> {
                         it.type = Lesson.TYPE_NORMAL
@@ -75,6 +74,8 @@ class MobidziennikApiTimetable(val data: DataMobidziennik, rows: List<String>) {
                     }
                 }
 
+                it.id = it.buildId()
+
                 val seen = profile.empty || date < Date.getToday()
 
                 if (it.type != Lesson.TYPE_NORMAL) {
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/vulcan/data/api/VulcanApiTimetable.kt b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/vulcan/data/api/VulcanApiTimetable.kt
index 080922e6..0ece5b64 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/vulcan/data/api/VulcanApiTimetable.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/vulcan/data/api/VulcanApiTimetable.kt
@@ -114,9 +114,7 @@ class VulcanApiTimetable(override val data: DataVulcan, val onSuccess: () -> Uni
                     }
                 }
 
-                val id = lessonDate.combineWith(startTime) / 6L * 10L + (lesson.hashCode() and 0xFFFF)
-
-                val lessonObject = Lesson(profileId, id).apply {
+                val lessonObject = Lesson(profileId, -1).apply {
                     this.type = type
 
                     when (type) {
@@ -170,6 +168,8 @@ class VulcanApiTimetable(override val data: DataVulcan, val onSuccess: () -> Uni
                             }
                         }
                     }
+
+                    this.id = buildId()
                 }
 
                 val seen = profile.empty || lessonDate < Date.getToday()
@@ -178,7 +178,7 @@ class VulcanApiTimetable(override val data: DataVulcan, val onSuccess: () -> Uni
                     data.metadataList.add(Metadata(
                             profileId,
                             Metadata.TYPE_LESSON_CHANGE,
-                            id,
+                            lessonObject.id,
                             seen,
                             seen,
                             System.currentTimeMillis()
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/db/modules/timetable/Lesson.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/modules/timetable/Lesson.kt
index 38834b30..d032bb77 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/db/modules/timetable/Lesson.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/modules/timetable/Lesson.kt
@@ -15,7 +15,7 @@ import pl.szczodrzynski.edziennik.utils.models.Time
             Index(value = ["profileId", "type", "date"]),
             Index(value = ["profileId", "type", "oldDate"])
         ])
-open class Lesson(val profileId: Int, @PrimaryKey val id: Long) {
+open class Lesson(val profileId: Int, @PrimaryKey var id: Long) {
     companion object {
         const val TYPE_NO_LESSONS = -1
         const val TYPE_NORMAL = 0
@@ -45,6 +45,22 @@ open class Lesson(val profileId: Int, @PrimaryKey val id: Long) {
     var oldTeamId: Long? = null
     var oldClassroom: String? = null
 
+    val displayDate: Date?
+        get() {
+            if (type == TYPE_SHIFTED_SOURCE)
+                return oldDate
+            return date ?: oldDate
+        }
+
+    val displayStartTime: Time?
+        get() {
+            if (type == TYPE_SHIFTED_SOURCE)
+                return oldStartTime
+            return startTime ?: oldStartTime
+        }
+
+    fun buildId(): Long = (displayDate?.combineWith(displayStartTime) ?: 0L) / 6L * 10L + (hashCode() and 0xFFFF)
+
     override fun toString(): String {
         return "Lesson(profileId=$profileId, " +
                 "id=$id, " +
@@ -66,6 +82,55 @@ open class Lesson(val profileId: Int, @PrimaryKey val id: Long) {
                 "oldTeamId=$oldTeamId, " +
                 "oldClassroom=$oldClassroom)"
     }
+
+    override fun equals(other: Any?): Boolean {
+        if (this === other) return true
+        if (other !is Lesson) return false
+
+        if (profileId != other.profileId) return false
+        if (id != other.id) return false
+        if (type != other.type) return false
+        if (date != other.date) return false
+        if (lessonNumber != other.lessonNumber) return false
+        if (startTime != other.startTime) return false
+        if (endTime != other.endTime) return false
+        if (subjectId != other.subjectId) return false
+        if (teacherId != other.teacherId) return false
+        if (teamId != other.teamId) return false
+        if (classroom != other.classroom) return false
+        if (oldDate != other.oldDate) return false
+        if (oldLessonNumber != other.oldLessonNumber) return false
+        if (oldStartTime != other.oldStartTime) return false
+        if (oldEndTime != other.oldEndTime) return false
+        if (oldSubjectId != other.oldSubjectId) return false
+        if (oldTeacherId != other.oldTeacherId) return false
+        if (oldTeamId != other.oldTeamId) return false
+        if (oldClassroom != other.oldClassroom) return false
+
+        return true
+    }
+
+    override fun hashCode(): Int {
+        var result = profileId
+        result = 31 * result + type
+        result = 31 * result + (date?.hashCode() ?: 0)
+        result = 31 * result + (lessonNumber ?: 0)
+        result = 31 * result + (startTime?.hashCode() ?: 0)
+        result = 31 * result + (endTime?.hashCode() ?: 0)
+        result = 31 * result + (subjectId?.hashCode() ?: 0)
+        result = 31 * result + (teacherId?.hashCode() ?: 0)
+        result = 31 * result + (teamId?.hashCode() ?: 0)
+        result = 31 * result + (classroom?.hashCode() ?: 0)
+        result = 31 * result + (oldDate?.hashCode() ?: 0)
+        result = 31 * result + (oldLessonNumber ?: 0)
+        result = 31 * result + (oldStartTime?.hashCode() ?: 0)
+        result = 31 * result + (oldEndTime?.hashCode() ?: 0)
+        result = 31 * result + (oldSubjectId?.hashCode() ?: 0)
+        result = 31 * result + (oldTeacherId?.hashCode() ?: 0)
+        result = 31 * result + (oldTeamId?.hashCode() ?: 0)
+        result = 31 * result + (oldClassroom?.hashCode() ?: 0)
+        return result
+    }
 }
 /*
 DROP TABLE lessons;
@@ -94,4 +159,4 @@ CREATE TABLE lessons (
 
 	PRIMARY KEY(profileId)
 );
-*/
\ No newline at end of file
+*/
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/db/modules/timetable/LessonFull.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/modules/timetable/LessonFull.kt
index 04d35f8e..a0c15e16 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/db/modules/timetable/LessonFull.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/modules/timetable/LessonFull.kt
@@ -2,7 +2,6 @@ package pl.szczodrzynski.edziennik.data.db.modules.timetable
 
 import android.content.Context
 import pl.szczodrzynski.edziennik.R
-import pl.szczodrzynski.edziennik.utils.models.Date
 import pl.szczodrzynski.edziennik.utils.models.Time
 
 class LessonFull(profileId: Int, id: Long) : Lesson(profileId, id) {
@@ -13,13 +12,6 @@ class LessonFull(profileId: Int, id: Long) : Lesson(profileId, id) {
     var oldTeacherName: String? = null
     var oldTeamName: String? = null
 
-    val displayDate: Date?
-        get() {
-            if (type == TYPE_SHIFTED_SOURCE)
-                return oldDate
-            return date ?: oldDate
-        }
-
     val displayLessonNumber: Int?
         get() {
             if (type == TYPE_SHIFTED_SOURCE)
@@ -27,13 +19,6 @@ class LessonFull(profileId: Int, id: Long) : Lesson(profileId, id) {
             return lessonNumber ?: oldLessonNumber
         }
 
-    val displayStartTime: Time?
-        get() {
-            if (type == TYPE_SHIFTED_SOURCE)
-                return oldStartTime
-            return startTime ?: oldStartTime
-        }
-
     val displayEndTime: Time?
         get() {
             if (type == TYPE_SHIFTED_SOURCE)
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/utils/models/Date.java b/app/src/main/java/pl/szczodrzynski/edziennik/utils/models/Date.java
index fd62d3e4..4e332863 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/utils/models/Date.java
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/utils/models/Date.java
@@ -272,4 +272,12 @@ public class Date implements Comparable<Date> {
                 ", day=" + day +
                 '}';
     }
+
+    @Override
+    public int hashCode() {
+        int result = year;
+        result = 31 * result + month;
+        result = 31 * result + day;
+        return result;
+    }
 }
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/utils/models/Time.java b/app/src/main/java/pl/szczodrzynski/edziennik/utils/models/Time.java
index 3b951751..1f1d1089 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/utils/models/Time.java
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/utils/models/Time.java
@@ -121,7 +121,7 @@ public class Time implements Comparable<Time> {
 
     public String getStringValue()
     {
-        return (hour < 10 ? "0" : "")+Integer.toString(hour)+(minute < 10 ? "0" : "")+Integer.toString(minute)+(second < 10 ? "0" : "")+Integer.toString(second);
+        return (hour < 10 ? "0" : "")+ hour +(minute < 10 ? "0" : "")+ minute +(second < 10 ? "0" : "")+ second;
     }
 
     public String getStringHM()
@@ -129,18 +129,18 @@ public class Time implements Comparable<Time> {
         if (hour < 0) {
             return "";
         }
-        return Integer.toString(hour)+":"+(minute < 10 ? "0" : "")+Integer.toString(minute);
+        return hour +":"+(minute < 10 ? "0" : "")+ minute;
     }
     public String getStringH_M()
     {
         if (hour < 0) {
             return "";
         }
-        return Integer.toString(hour)+"-"+(minute < 10 ? "0" : "")+Integer.toString(minute);
+        return hour +"-"+(minute < 10 ? "0" : "")+ minute;
     }
     public String getStringHMS()
     {
-        return Integer.toString(hour)+":"+(minute < 10 ? "0" : "")+Integer.toString(minute)+":"+(second < 10 ? "0" : "")+Integer.toString(second);
+        return hour +":"+(minute < 10 ? "0" : "")+ minute +":"+(second < 10 ? "0" : "")+ second;
     }
 
     public static Time getNow()
@@ -194,4 +194,12 @@ public class Time implements Comparable<Time> {
                 ", second=" + second +
                 '}';
     }
+
+    @Override
+    public int hashCode() {
+        int result = hour;
+        result = 31 * result + minute;
+        result = 31 * result + second;
+        return result;
+    }
 }