From 7c3e13114fd189c49e86b8d6c200ffb3c27bb498 Mon Sep 17 00:00:00 2001 From: Iván Ávalos Date: Fri, 14 Jan 2022 18:25:26 -0600 Subject: Refactored reports code into ReportController.kt and added extra report periods --- .../TrackerMap/client/models/EventInformation.kt | 3 +- .../TrackerMap/controllers/ReportController.kt | 134 +++++++++++++++++++++ .../mx/trackermap/TrackerMap/utils/Formatter.kt | 8 +- .../mx/trackermap/TrackerMap/utils/ReportDates.kt | 79 ++++++++++++ 4 files changed, 220 insertions(+), 4 deletions(-) create mode 100644 shared/src/commonMain/kotlin/mx/trackermap/TrackerMap/controllers/ReportController.kt create mode 100644 shared/src/commonMain/kotlin/mx/trackermap/TrackerMap/utils/ReportDates.kt (limited to 'shared') diff --git a/shared/src/commonMain/kotlin/mx/trackermap/TrackerMap/client/models/EventInformation.kt b/shared/src/commonMain/kotlin/mx/trackermap/TrackerMap/client/models/EventInformation.kt index 1256b8c..c4f91fe 100644 --- a/shared/src/commonMain/kotlin/mx/trackermap/TrackerMap/client/models/EventInformation.kt +++ b/shared/src/commonMain/kotlin/mx/trackermap/TrackerMap/client/models/EventInformation.kt @@ -2,5 +2,6 @@ package mx.trackermap.TrackerMap.client.models data class EventInformation( val event: Event, - val position: Position? + val position: Position?, + val geofence: Geofence? ) diff --git a/shared/src/commonMain/kotlin/mx/trackermap/TrackerMap/controllers/ReportController.kt b/shared/src/commonMain/kotlin/mx/trackermap/TrackerMap/controllers/ReportController.kt new file mode 100644 index 0000000..2151331 --- /dev/null +++ b/shared/src/commonMain/kotlin/mx/trackermap/TrackerMap/controllers/ReportController.kt @@ -0,0 +1,134 @@ +package mx.trackermap.TrackerMap.controllers + +import android.util.Log +import kotlinx.coroutines.DelicateCoroutinesApi +import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.launch +import mx.trackermap.TrackerMap.client.apis.GeofencesApi +import mx.trackermap.TrackerMap.client.apis.ReportsApi +import mx.trackermap.TrackerMap.client.models.EventInformation +import mx.trackermap.TrackerMap.client.models.Position +import mx.trackermap.TrackerMap.client.models.Stop +import mx.trackermap.TrackerMap.utils.ReportDates + +@DelicateCoroutinesApi +class ReportController( + private val reportsApi: ReportsApi, + private val geofencesApi: GeofencesApi +) { + + sealed class Report { + class PositionsReport(val positions: Array) : Report() + class EventsReport(val events: Array) : Report() + class StopsReport(val stops: Array) : Report() + class XlsxReport(val data: ByteArray) : Report() + object LoadingReport: Report() + } + + enum class ReportType { + POSITIONS, EVENTS, STOPS + } + + val reportFlow: MutableStateFlow = MutableStateFlow(Report.LoadingReport) + + fun fetchReport( + deviceId: Int, + reportType: ReportType?, + reportPeriod: ReportDates.ReportPeriod?, + xlsx: Boolean = false + ) { + if (reportType == null || reportPeriod == null) { + return + } + + val (currentDate, previousDate) = ReportDates.getDates(reportPeriod) + Log.d("UnitReportsVM", "Current report type: $reportType") + Log.d("UnitReportsVM", "Current report period: $reportType") + Log.d("UnitReportsVM", "Current date:${currentDate}") + Log.d("UnitReportsVM", "Previous date:${previousDate}") + + if (!xlsx) { + reportFlow.value = Report.LoadingReport + } + GlobalScope.launch { + when (reportType) { + ReportType.POSITIONS -> fetchPositions(deviceId, previousDate, currentDate, xlsx) + ReportType.EVENTS -> fetchEvents(deviceId, previousDate, currentDate, xlsx) + ReportType.STOPS -> fetchStops(deviceId, previousDate, currentDate, xlsx) + } + } + } + + private suspend fun fetchPositions( + deviceId: Int, + from: String, + to: String, + xlsx: Boolean + ) { + Log.d("UnitReportsVM", "Fetching positions") + + if (!xlsx) { + val result = reportsApi.reportsRouteGet(from, to, deviceId) + Log.d("UnitReportsVM", "Positions report: $result") + reportFlow.value = Report.PositionsReport(result) + } else { + val result = reportsApi.reportsRouteGetXlsx(from, to, deviceId) + Log.d("UnitReportsVM", "Positions report: $result") + reportFlow.value = Report.XlsxReport(result) + } + + } + + private suspend fun fetchEvents( + deviceId: Int, + from: String, + to: String, + xlsx: Boolean + ) { + Log.d("UnitReportsVM", "Fetching events") + + if (!xlsx) { + val positionsResult = reportsApi.reportsRouteGet(from, to, deviceId) + val eventsResult = reportsApi.reportsEventsGet(from, to, deviceId) + val geofencesResult = geofencesApi.geofencesGet(all = true) + + val result = mutableListOf() + eventsResult.forEach { event -> + result.add(EventInformation( + event = event, + position = positionsResult.find { it.id == event.positionId }, + geofence = geofencesResult.find { it.id == event.geofenceId } + )) + } + + Log.d("UnitReportsVM", "Events report: $result") + reportFlow.value = Report.EventsReport(result.toTypedArray()) + } else { + val result = reportsApi.reportsEventsGetXlsx(from, to, deviceId) + + Log.d("UnitReportsVM", "Events report: $result") + reportFlow.value = Report.XlsxReport(result) + } + } + + private suspend fun fetchStops( + deviceId: Int, + from: String, + to: String, + xlsx: Boolean + ) { + Log.d("UnitReportsVM", "Fetching stops") + + if (!xlsx) { + val result = reportsApi.reportsStopsGet(from, to, deviceId) + Log.d("UnitReportsVM", "Stops report: $result") + reportFlow.value = Report.StopsReport(result) + } else { + val result = reportsApi.reportsStopsGetXlsx(from, to, deviceId) + Log.d("UnitReportsVM", "Stops report: $result") + reportFlow.value = Report.XlsxReport(result) + } + + } +} \ No newline at end of file diff --git a/shared/src/commonMain/kotlin/mx/trackermap/TrackerMap/utils/Formatter.kt b/shared/src/commonMain/kotlin/mx/trackermap/TrackerMap/utils/Formatter.kt index af4e14d..878418e 100644 --- a/shared/src/commonMain/kotlin/mx/trackermap/TrackerMap/utils/Formatter.kt +++ b/shared/src/commonMain/kotlin/mx/trackermap/TrackerMap/utils/Formatter.kt @@ -5,9 +5,11 @@ import kotlin.math.round class Formatter { companion object { - fun formatDate(date: String): String { - return date.substring(0 until date.indexOf('+')) - .toLocalDateTime().toString().replace('T', ' ') + fun formatDate(str: String): String { + val timezone = TimeZone.currentSystemDefault() + val date = str.toInstant().toLocalDateTime(timezone).toString() + return date + .replace('T', ' ').trim('Z') } fun formatSpeed(speed: Double, unit: SpeedUnit): String { diff --git a/shared/src/commonMain/kotlin/mx/trackermap/TrackerMap/utils/ReportDates.kt b/shared/src/commonMain/kotlin/mx/trackermap/TrackerMap/utils/ReportDates.kt new file mode 100644 index 0000000..360cce8 --- /dev/null +++ b/shared/src/commonMain/kotlin/mx/trackermap/TrackerMap/utils/ReportDates.kt @@ -0,0 +1,79 @@ +package mx.trackermap.TrackerMap.utils + +import kotlinx.coroutines.DelicateCoroutinesApi +import kotlinx.datetime.* + +@DelicateCoroutinesApi +class ReportDates { + enum class ReportPeriod { + TODAY, LAST_24, YESTERDAY, THIS_WEEK, LAST_7, THIS_MONTH, LAST_30 + } + + companion object { + private fun formatDateTime(dateTime: LocalDateTime, timezone: TimeZone) = + dateTime.toInstant(timezone).toString() + + fun getDates(period: ReportPeriod): Pair { + val timezone = TimeZone.currentSystemDefault() + val clock = Clock.System + val instant = clock.now() + val dateTime = instant.toLocalDateTime(timezone) + val date = dateTime.date + + var currentDate: LocalDateTime? = null + var previousDate: LocalDateTime? = null + when (period) { + ReportPeriod.TODAY -> { + previousDate = date.atTime(0, 0) + currentDate = dateTime + } + ReportPeriod.LAST_24 -> { + previousDate = instant + .minus(1, DateTimeUnit.DAY, timezone) + .toLocalDateTime(timezone) + currentDate = dateTime + } + ReportPeriod.YESTERDAY -> { + val yesterday = instant + .minus(1, DateTimeUnit.DAY, timezone) + .toLocalDateTime(timezone).date + previousDate = yesterday.atTime(0, 0) + currentDate = yesterday.atTime(23, 59) + } + ReportPeriod.THIS_WEEK -> { + previousDate = instant + .minus(date.dayOfWeek.isoDayNumber - 1, DateTimeUnit.DAY, timezone) + .toLocalDateTime(timezone).date + .atTime(0, 0) + currentDate = dateTime + } + ReportPeriod.LAST_7 -> { + previousDate = instant + .minus(1, DateTimeUnit.WEEK, timezone) + .toLocalDateTime(timezone).date + .atTime(0, 0) + currentDate = dateTime + } + ReportPeriod.THIS_MONTH -> { + previousDate = instant + .minus(date.dayOfMonth - 1, DateTimeUnit.DAY, timezone) + .toLocalDateTime(timezone).date + .atTime(0, 0) + currentDate = dateTime + } + ReportPeriod.LAST_30 -> { + previousDate = instant + .minus(1, DateTimeUnit.MONTH, timezone) + .toLocalDateTime(timezone).date + .atTime(0, 0) + currentDate = dateTime + } + } + + return Pair( + formatDateTime(currentDate, timezone), + formatDateTime(previousDate, timezone) + ) + } + } +} \ No newline at end of file -- cgit v1.2.3