diff options
author | Iván Ávalos <avalos@disroot.org> | 2022-01-13 20:22:36 -0600 |
---|---|---|
committer | Iván Ávalos <avalos@disroot.org> | 2022-01-13 20:22:36 -0600 |
commit | 5bd8ab38cd1549b267ff93fd1ea93f1c0ca9d8ab (patch) | |
tree | fdf5444004231bf276054e9d513007d67f9ece77 | |
parent | feef38c8d9befd5dbd53bea22725f7922138df2d (diff) | |
download | etbsa-trackermap-mobile-5bd8ab38cd1549b267ff93fd1ea93f1c0ca9d8ab.tar.gz etbsa-trackermap-mobile-5bd8ab38cd1549b267ff93fd1ea93f1c0ca9d8ab.tar.bz2 etbsa-trackermap-mobile-5bd8ab38cd1549b267ff93fd1ea93f1c0ca9d8ab.zip |
Implemented base for exporting XLSX reports
6 files changed, 211 insertions, 80 deletions
diff --git a/androidApp/src/main/java/mx/trackermap/TrackerMap/android/details/reports/UnitReportsFragment.kt b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/details/reports/UnitReportsFragment.kt index 43f879d..2cb2d9a 100644 --- a/androidApp/src/main/java/mx/trackermap/TrackerMap/android/details/reports/UnitReportsFragment.kt +++ b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/details/reports/UnitReportsFragment.kt @@ -78,6 +78,9 @@ class UnitReportsFragment : Fragment() { binding.periodButton.setOnClickListener { showPeriodPopUp(it) } + binding.exportButton.setOnClickListener { + unitReportsViewModel.fetchReportXlsx() + } unitReportsViewModel.setReportPeriod(UnitReportsViewModel.ReportPeriod.DAY) unitReportsViewModel.setReportType(UnitReportsViewModel.ReportType.POSITIONS) } diff --git a/androidApp/src/main/java/mx/trackermap/TrackerMap/android/details/reports/UnitReportsViewModel.kt b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/details/reports/UnitReportsViewModel.kt index 48486e1..851516e 100644 --- a/androidApp/src/main/java/mx/trackermap/TrackerMap/android/details/reports/UnitReportsViewModel.kt +++ b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/details/reports/UnitReportsViewModel.kt @@ -112,7 +112,11 @@ class UnitReportsViewModel( return Pair(currentDate, previousDate) } - private fun fetchReport() { + fun fetchReportXlsx() { + fetchReport(true) + } + + private fun fetchReport(xlsx: Boolean = false) { if (_reportType.value == null || _reportPeriod.value == null) { return } @@ -126,64 +130,91 @@ class UnitReportsViewModel( _report.postValue(Report.LoadingReport) viewModelScope.launch { when (_reportType.value!!) { - ReportType.POSITIONS -> fetchPositions(previousDate, currentDate) - ReportType.EVENTS -> fetchEvents(previousDate, currentDate) - ReportType.STOPS -> fetchStops(previousDate, currentDate) + ReportType.POSITIONS -> fetchPositions(previousDate, currentDate, xlsx) + ReportType.EVENTS -> fetchEvents(previousDate, currentDate, xlsx) + ReportType.STOPS -> fetchStops(previousDate, currentDate, xlsx) } } } - private suspend fun fetchPositions(from: Date, to: Date) { + private suspend fun fetchPositions(from: Date, to: Date, xlsx: Boolean) { Log.d("UnitReportsVM", "Fetching positions") - val result = reportsApi.reportsRouteGet( - dateFormat.format(from), - dateFormat.format(to), - _deviceId.value!! - ) + if (!xlsx) { + val result = reportsApi.reportsRouteGet( + dateFormat.format(from), + dateFormat.format(to), + _deviceId.value!! + ) + Log.d("UnitReportsVM", "Positions report: $result") + _report.postValue(Report.PositionsReport(result)) + } else { + val result = reportsApi.reportsRouteGetXlsx( + dateFormat.format(from), + dateFormat.format(to), + _deviceId.value!! + ) + Log.d("UnitReportsVM", "Positions report: $result") + } - Log.d("UnitReportsVM", "Positions report: $result") - _report.postValue(Report.PositionsReport(result)) } - private suspend fun fetchEvents(from: Date, to: Date) { + private suspend fun fetchEvents(from: Date, to: Date, xlsx: Boolean) { Log.d("UnitReportsVM", "Fetching events") - val positionsResult = reportsApi.reportsRouteGet( - dateFormat.format(from), - dateFormat.format(to), - _deviceId.value!! - ) - - val eventsResult = reportsApi.reportsEventsGet( - dateFormat.format(from), - dateFormat.format(to), - _deviceId.value!! - ) - - val result = mutableListOf<EventInformation>() + if (!xlsx) { + val positionsResult = reportsApi.reportsRouteGet( + dateFormat.format(from), + dateFormat.format(to), + _deviceId.value!! + ) + + val eventsResult = reportsApi.reportsEventsGet( + dateFormat.format(from), + dateFormat.format(to), + _deviceId.value!! + ) + + val result = mutableListOf<EventInformation>() + + eventsResult.forEach { event -> + result.add(EventInformation( + event = event, + position = positionsResult.find { it.id == event.positionId } + )) + } - eventsResult.forEach { event -> - result.add(EventInformation( - event = event, - position = positionsResult.find { it.id == event.positionId } - )) + Log.d("UnitReportsVM", "Events report: $result") + _report.postValue(Report.EventsReport(result.toTypedArray())) + } else { + val result = reportsApi.reportsEventsGetXlsx( + dateFormat.format(from), + dateFormat.format(to), + _deviceId.value!! + ) + Log.d("UnitReportsVM", "Events report: $result") } - - Log.d("UnitReportsVM", "Events report: $result") - _report.postValue(Report.EventsReport(result.toTypedArray())) } - private suspend fun fetchStops(from: Date, to: Date) { + private suspend fun fetchStops(from: Date, to: Date, xlsx: Boolean) { Log.d("UnitReportsVM", "Fetching stops") - val result = reportsApi.reportsStopsGet( - dateFormat.format(from), - dateFormat.format(to), - _deviceId.value!! - ) + if (!xlsx) { + val result = reportsApi.reportsStopsGet( + dateFormat.format(from), + dateFormat.format(to), + _deviceId.value!! + ) + Log.d("UnitReportsVM", "Stops report: $result") + _report.postValue(Report.StopsReport(result)) + } else { + val result = reportsApi.reportsStopsGetXlsx( + dateFormat.format(from), + dateFormat.format(to), + _deviceId.value!! + ) + Log.d("UnitReportsVM", "Stops report: $result") + } - Log.d("UnitReportsVM", "Stops report: $result") - _report.postValue(Report.StopsReport(result)) } }
\ No newline at end of file diff --git a/androidApp/src/main/res/layout/unit_details_reports.xml b/androidApp/src/main/res/layout/unit_details_reports.xml index dc649e4..0a8e23d 100644 --- a/androidApp/src/main/res/layout/unit_details_reports.xml +++ b/androidApp/src/main/res/layout/unit_details_reports.xml @@ -102,10 +102,17 @@ android:id="@+id/periodButton" android:layout_width="wrap_content" android:layout_height="wrap_content" + android:layout_marginEnd="@dimen/fields_spacing" android:text="@string/select_period" android:textColor="@color/colorPrimaryDark" app:backgroundTint="@color/darkBackground" /> + <com.google.android.material.button.MaterialButton + android:id="@+id/exportButton" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/export_report" /> + </LinearLayout> <com.addisonelliott.segmentedbutton.SegmentedButtonGroup diff --git a/androidApp/src/main/res/values-es-rMX/strings.xml b/androidApp/src/main/res/values-es-rMX/strings.xml index 6aee861..0b4f4b3 100644 --- a/androidApp/src/main/res/values-es-rMX/strings.xml +++ b/androidApp/src/main/res/values-es-rMX/strings.xml @@ -81,6 +81,7 @@ <string name="month_period">Mes</string> <string name="period">Periodo</string> <string name="select_period">Seleccionar</string> + <string name="export_report">Exportar</string> <string name="table_event">Evento</string> <string name="table_datetime">Fecha y hora</string> diff --git a/androidApp/src/main/res/values/strings.xml b/androidApp/src/main/res/values/strings.xml index 5f39ce1..268f5d5 100644 --- a/androidApp/src/main/res/values/strings.xml +++ b/androidApp/src/main/res/values/strings.xml @@ -102,6 +102,7 @@ <string name="month_period">Month</string> <string name="period">Period</string> <string name="select_period">Select</string> + <string name="export_report">Export</string> <string name="table_event">Event</string> <string name="table_datetime">Datetime</string> diff --git a/shared/src/commonMain/kotlin/mx/trackermap/TrackerMap/client/apis/ReportsApi.kt b/shared/src/commonMain/kotlin/mx/trackermap/TrackerMap/client/apis/ReportsApi.kt index 43feaa6..b4d6f74 100644 --- a/shared/src/commonMain/kotlin/mx/trackermap/TrackerMap/client/apis/ReportsApi.kt +++ b/shared/src/commonMain/kotlin/mx/trackermap/TrackerMap/client/apis/ReportsApi.kt @@ -11,6 +11,7 @@ */ package mx.trackermap.TrackerMap.client.apis +import io.ktor.content.* import mx.trackermap.TrackerMap.client.models.Event import mx.trackermap.TrackerMap.client.models.Position import mx.trackermap.TrackerMap.client.models.Stop @@ -19,7 +20,7 @@ import mx.trackermap.TrackerMap.client.models.ReportTrips import mx.trackermap.TrackerMap.client.infrastructure.* -class ReportsApi(basePath: kotlin.String = "https://demo.traccar.org/api") : ApiClient(basePath) { +class ReportsApi(basePath: String = "https://demo.traccar.org/api") : ApiClient(basePath) { /** * Fetch a list of Events within the time period for the Devices or Groups @@ -31,27 +32,38 @@ class ReportsApi(basePath: kotlin.String = "https://demo.traccar.org/api") : Api * @param type % can be used to return events of all types (optional) * @return kotlin.Array<Event> */ - @Suppress("UNCHECKED_CAST") - suspend fun reportsEventsGet( + private suspend fun reportsEventsGetBase( from: String, to: String, - deviceId: Int - ): kotlin.Array<Event> { + deviceId: Int, + xlsx: Boolean = false + ): Any { val localVariableQuery: MultiValueMap = mapOf( "deviceId" to toMultiValue(listOf(deviceId), "multi"), "from" to listOf(from), "to" to listOf(to) ) + val localVariableHeaders = mutableMapOf<String, String>() + if (xlsx) { + localVariableHeaders["Accept"] = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" + } val localVariableConfig = RequestConfig( RequestMethod.GET, - "/reports/events", query = localVariableQuery - ) - val response = request<kotlin.Array<Event>>( - localVariableConfig + "/reports/events", query = localVariableQuery, + headers = localVariableHeaders ) + val response = if (xlsx) { + request<ByteArray>( + localVariableConfig + ) + } else { + request<Array<Event>>( + localVariableConfig + ) + } return when (response.responseType) { - ResponseType.Success -> (response as Success<*>).data as kotlin.Array<Event> + ResponseType.Success -> (response as Success<*>).data!! ResponseType.Informational -> TODO() ResponseType.Redirection -> TODO() ResponseType.ClientError -> throw ClientException( @@ -63,6 +75,24 @@ class ReportsApi(basePath: kotlin.String = "https://demo.traccar.org/api") : Api } } + @Suppress("UNCHECKED_CAST") + suspend fun reportsEventsGet( + from: String, + to: String, + deviceId: Int, + ): Array<Event> { + return reportsEventsGetBase(from, to, deviceId, false) as Array<Event> + } + + @Suppress("UNCHECKED_CAST") + suspend fun reportsEventsGetXlsx( + from: String, + to: String, + deviceId: Int, + ): ByteArray { + return reportsEventsGetBase(from, to, deviceId, true) as ByteArray + } + /** * Fetch a list of Positions within the time period for the Devices or Groups * At least one _deviceId_ or one _groupId_ must be passed @@ -72,27 +102,38 @@ class ReportsApi(basePath: kotlin.String = "https://demo.traccar.org/api") : Api * @param groupId (optional) * @return kotlin.Array<Position> */ - @Suppress("UNCHECKED_CAST") - suspend fun reportsRouteGet( + private suspend fun reportsRouteGetBase( from: String, to: String, - deviceId: Int - ): kotlin.Array<Position> { + deviceId: Int, + xlsx: Boolean = false + ): Any { val localVariableQuery: MultiValueMap = mapOf( "deviceId" to toMultiValue(listOf(deviceId), "multi"), "from" to listOf(from), "to" to listOf(to) ) + val localVariableHeaders = mutableMapOf<String, String>() + if (xlsx) { + localVariableHeaders["Accept"] = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" + } val localVariableConfig = RequestConfig( RequestMethod.GET, - "/reports/route", query = localVariableQuery - ) - val response = request<kotlin.Array<Position>>( - localVariableConfig + "/reports/route", query = localVariableQuery, + headers = localVariableHeaders ) + val response = if (xlsx) { + request<ByteArray>( + localVariableConfig + ) + } else { + request<Array<Position>>( + localVariableConfig + ) + } return when (response.responseType) { - ResponseType.Success -> (response as Success<*>).data as kotlin.Array<Position> + ResponseType.Success -> (response as Success<*>).data!! ResponseType.Informational -> TODO() ResponseType.Redirection -> TODO() ResponseType.ClientError -> throw ClientException( @@ -104,6 +145,24 @@ class ReportsApi(basePath: kotlin.String = "https://demo.traccar.org/api") : Api } } + @Suppress("UNCHECKED_CAST") + suspend fun reportsRouteGet( + from: String, + to: String, + deviceId: Int, + ): Array<Position> { + return reportsRouteGetBase(from, to, deviceId, false) as Array<Position> + } + + @Suppress("UNCHECKED_CAST") + suspend fun reportsRouteGetXlsx( + from: String, + to: String, + deviceId: Int, + ): ByteArray { + return reportsRouteGetBase(from, to, deviceId, true) as ByteArray + } + /** * Fetch a list of ReportStops within the time period for the Devices or Groups * At least one _deviceId_ or one _groupId_ must be passed @@ -113,27 +172,38 @@ class ReportsApi(basePath: kotlin.String = "https://demo.traccar.org/api") : Api * @param groupId (optional) * @return kotlin.Array<ReportStops> */ - @Suppress("UNCHECKED_CAST") - suspend fun reportsStopsGet( + private suspend fun reportsStopsGetBase( from: String, to: String, - deviceId: Int - ): kotlin.Array<Stop> { + deviceId: Int, + xlsx: Boolean = false + ): Any { val localVariableQuery: MultiValueMap = mapOf( "deviceId" to toMultiValue(listOf(deviceId), "multi"), "from" to listOf(from), "to" to listOf(to) ) + val localVariableHeaders = mutableMapOf<String, String>() + if (xlsx) { + localVariableHeaders["Accept"] = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" + } val localVariableConfig = RequestConfig( RequestMethod.GET, - "/reports/stops", query = localVariableQuery - ) - val response = request<kotlin.Array<Stop>>( - localVariableConfig + "/reports/stops", query = localVariableQuery, + headers = localVariableHeaders ) + val response = if (xlsx) { + request<ByteArray>( + localVariableConfig + ) + } else { + request<Array<Stop>>( + localVariableConfig + ) + } return when (response.responseType) { - ResponseType.Success -> (response as Success<*>).data as kotlin.Array<Stop> + ResponseType.Success -> (response as Success<*>).data!! ResponseType.Informational -> TODO() ResponseType.Redirection -> TODO() ResponseType.ClientError -> throw ClientException( @@ -145,6 +215,24 @@ class ReportsApi(basePath: kotlin.String = "https://demo.traccar.org/api") : Api } } + @Suppress("UNCHECKED_CAST") + suspend fun reportsStopsGet( + from: String, + to: String, + deviceId: Int, + ): Array<Stop> { + return reportsStopsGetBase(from, to, deviceId, false) as Array<Stop> + } + + @Suppress("UNCHECKED_CAST") + suspend fun reportsStopsGetXlsx( + from: String, + to: String, + deviceId: Int, + ): ByteArray { + return reportsStopsGetBase(from, to, deviceId, true) as ByteArray + } + /** * Fetch a list of ReportSummary within the time period for the Devices or Groups * At least one _deviceId_ or one _groupId_ must be passed @@ -158,9 +246,9 @@ class ReportsApi(basePath: kotlin.String = "https://demo.traccar.org/api") : Api suspend fun reportsSummaryGet( from: java.time.LocalDateTime, to: java.time.LocalDateTime, - deviceId: kotlin.Array<kotlin.Int>? = null, - groupId: kotlin.Array<kotlin.Int>? = null - ): kotlin.Array<ReportSummary> { + deviceId: Array<Int>? = null, + groupId: Array<Int>? = null + ): Array<ReportSummary> { val localVariableQuery: MultiValueMap = mapOf( "deviceId" to toMultiValue(deviceId!!.toList(), "multi"), "groupId" to toMultiValue(groupId!!.toList(), "multi"), @@ -171,12 +259,12 @@ class ReportsApi(basePath: kotlin.String = "https://demo.traccar.org/api") : Api RequestMethod.GET, "/reports/summary", query = localVariableQuery ) - val response = request<kotlin.Array<ReportSummary>>( + val response = request<Array<ReportSummary>>( localVariableConfig ) return when (response.responseType) { - ResponseType.Success -> (response as Success<*>).data as kotlin.Array<ReportSummary> + ResponseType.Success -> (response as Success<*>).data as Array<ReportSummary> ResponseType.Informational -> TODO() ResponseType.Redirection -> TODO() ResponseType.ClientError -> throw ClientException( @@ -201,9 +289,9 @@ class ReportsApi(basePath: kotlin.String = "https://demo.traccar.org/api") : Api suspend fun reportsTripsGet( from: java.time.LocalDateTime, to: java.time.LocalDateTime, - deviceId: kotlin.Array<kotlin.Int>? = null, - groupId: kotlin.Array<kotlin.Int>? = null - ): kotlin.Array<ReportTrips> { + deviceId: Array<Int>? = null, + groupId: Array<Int>? = null + ): Array<ReportTrips> { val localVariableQuery: MultiValueMap = mapOf( "deviceId" to toMultiValue(deviceId!!.toList(), "multi"), "groupId" to toMultiValue(groupId!!.toList(), "multi"), @@ -214,12 +302,12 @@ class ReportsApi(basePath: kotlin.String = "https://demo.traccar.org/api") : Api RequestMethod.GET, "/reports/trips", query = localVariableQuery ) - val response = request<kotlin.Array<ReportTrips>>( + val response = request<Array<ReportTrips>>( localVariableConfig ) return when (response.responseType) { - ResponseType.Success -> (response as Success<*>).data as kotlin.Array<ReportTrips> + ResponseType.Success -> (response as Success<*>).data as Array<ReportTrips> ResponseType.Informational -> TODO() ResponseType.Redirection -> TODO() ResponseType.ClientError -> throw ClientException( |