From 5259951de702a8e827701e227fc564b7cffa8066 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 --- .../mx/trackermap/TrackerMap/android/TrackerApp.kt | 4 +- .../android/details/reports/UnitReportsFragment.kt | 83 +++++----- .../details/reports/UnitReportsViewModel.kt | 179 +++------------------ .../src/main/res/menu/report_period_options.xml | 28 +++- androidApp/src/main/res/values-es-rMX/strings.xml | 12 +- androidApp/src/main/res/values/strings.xml | 12 +- 6 files changed, 109 insertions(+), 209 deletions(-) (limited to 'androidApp/src/main') diff --git a/androidApp/src/main/java/mx/trackermap/TrackerMap/android/TrackerApp.kt b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/TrackerApp.kt index 4cbf8e5..d591b0b 100644 --- a/androidApp/src/main/java/mx/trackermap/TrackerMap/android/TrackerApp.kt +++ b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/TrackerApp.kt @@ -10,6 +10,7 @@ import mx.trackermap.TrackerMap.android.session.UserInformationViewModel import mx.trackermap.TrackerMap.android.units.UnitsViewModel import mx.trackermap.TrackerMap.client.apis.* import mx.trackermap.TrackerMap.controllers.GeofencesController +import mx.trackermap.TrackerMap.controllers.ReportController import mx.trackermap.TrackerMap.controllers.UnitsController import org.koin.android.ext.koin.androidContext import org.koin.android.ext.koin.androidLogger @@ -35,12 +36,13 @@ open class TrackerApp : Application() { factory { UnitsController(get(), get()) } factory { GeofencesController(get()) } + factory { ReportController(get(), get()) } viewModel { LoginViewModel(get(), get()) } viewModel { UnitInformationViewModel(get()) } viewModel { UnitCommandsViewModel(get()) } viewModel { UnitsViewModel(get()) } - viewModel { UnitReportsViewModel(get(), get()) } + viewModel { UnitReportsViewModel(get()) } viewModel { UserInformationViewModel(get()) } } 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 b67dd94..957c6a7 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 @@ -26,7 +26,9 @@ import mx.trackermap.TrackerMap.android.map.MarkerTransformations 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.controllers.ReportController import mx.trackermap.TrackerMap.utils.Formatter +import mx.trackermap.TrackerMap.utils.ReportDates import org.koin.androidx.viewmodel.ext.android.viewModel import java.lang.Exception import kotlin.math.max @@ -76,9 +78,9 @@ class UnitReportsFragment : Fragment() { binding.reportType.setOnPositionChangedListener { position -> unitReportsViewModel.setReportType( when (position) { - 0 -> UnitReportsViewModel.ReportType.POSITIONS - 1 -> UnitReportsViewModel.ReportType.EVENTS - else -> UnitReportsViewModel.ReportType.STOPS + 0 -> ReportController.ReportType.POSITIONS + 1 -> ReportController.ReportType.EVENTS + else -> ReportController.ReportType.STOPS } ) } @@ -88,8 +90,8 @@ class UnitReportsFragment : Fragment() { binding.exportButton.setOnClickListener { unitReportsViewModel.fetchReportXlsx() } - unitReportsViewModel.setReportPeriod(UnitReportsViewModel.ReportPeriod.DAY) - unitReportsViewModel.setReportType(UnitReportsViewModel.ReportType.POSITIONS) + unitReportsViewModel.setReportPeriod(ReportDates.ReportPeriod.TODAY) + unitReportsViewModel.setReportType(ReportController.ReportType.POSITIONS) } private fun setupObservers() { @@ -97,19 +99,22 @@ class UnitReportsFragment : Fragment() { Log.d("UnitReportsFragment", "Report available: $report") when (report) { - is UnitReportsViewModel.Report.PositionsReport -> { + is ReportController.Report.PositionsReport -> { display(report.positions) showMap(true) } - is UnitReportsViewModel.Report.EventsReport -> { + is ReportController.Report.EventsReport -> { display(report.events) showMap(false) } - is UnitReportsViewModel.Report.StopsReport -> { + is ReportController.Report.StopsReport -> { display(report.stops) showMap(true) } - is UnitReportsViewModel.Report.LoadingReport -> loading() + is ReportController.Report.XlsxReport -> { + downloadFile("report.xlsx") + } + is ReportController.Report.LoadingReport -> loading() } } @@ -121,21 +126,16 @@ class UnitReportsFragment : Fragment() { binding.periodButton.text = context?.getString( when (period) { - UnitReportsViewModel.ReportPeriod.DAY -> R.string.day_period - UnitReportsViewModel.ReportPeriod.WEEK -> R.string.week_period - UnitReportsViewModel.ReportPeriod.MONTH -> R.string.month_period + ReportDates.ReportPeriod.TODAY -> R.string.period_today + ReportDates.ReportPeriod.LAST_24 -> R.string.period_last_24 + ReportDates.ReportPeriod.YESTERDAY -> R.string.period_yesterday + ReportDates.ReportPeriod.THIS_WEEK -> R.string.period_this_week + ReportDates.ReportPeriod.LAST_7 -> R.string.period_last_7 + ReportDates.ReportPeriod.THIS_MONTH -> R.string.period_this_month + ReportDates.ReportPeriod.LAST_30 -> R.string.period_last_30 } ) } - - unitReportsViewModel.reportFile.observe(viewLifecycleOwner) { - downloadFile("report.xlsx") - } - - unitReportsViewModel.geofences.observe(viewLifecycleOwner) { geofences -> - Log.d("UnitReportsFragment", "Success $geofences") - reportsMapFragment.displayGeofences(geofences.values.toTypedArray()) - } } private fun showPeriodPopUp(view: View) { @@ -144,9 +144,14 @@ class UnitReportsFragment : Fragment() { popOver.setOnMenuItemClickListener { item -> unitReportsViewModel.setReportPeriod( when (item.itemId) { - R.id.dayOption -> UnitReportsViewModel.ReportPeriod.DAY - R.id.weekOption -> UnitReportsViewModel.ReportPeriod.WEEK - else -> UnitReportsViewModel.ReportPeriod.MONTH + R.id.optionToday -> ReportDates.ReportPeriod.TODAY + R.id.optionLast24 -> ReportDates.ReportPeriod.LAST_24 + R.id.optionYesterday -> ReportDates.ReportPeriod.YESTERDAY + R.id.optionWeek -> ReportDates.ReportPeriod.THIS_WEEK + R.id.optionLast7 -> ReportDates.ReportPeriod.LAST_7 + R.id.optionMonth -> ReportDates.ReportPeriod.THIS_MONTH + R.id.optionLast30 -> ReportDates.ReportPeriod.LAST_30 + else -> ReportDates.ReportPeriod.TODAY } ) true @@ -221,10 +226,8 @@ class UnitReportsFragment : Fragment() { else -> R.string.event_unknown }) } - event.event.geofenceId?.let { - val geofence = unitReportsViewModel.getGeofence(it) - Log.d("UnitReportsFragment", "Getting geofence $geofence") - geofenceText.text = geofence?.name + event.geofence?.let { + geofenceText.text = it.name } event.position?.let { addressText.text = it.address @@ -286,17 +289,19 @@ class UnitReportsFragment : Fragment() { private val createDocumentResult = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { if (it.resultCode == Activity.RESULT_OK) { - it?.data?.data?.also { uri -> - Log.d("UnitReportsFragment", "Downloading file into ${uri.path}") - val outputStream = context?.contentResolver?.openOutputStream(uri) - outputStream?.let { - try { - outputStream.write(unitReportsViewModel.reportFile.value) - outputStream.flush() - outputStream.close() - Log.d("UnitReportsFragment", "Wrote file into ${uri.path}") - } catch (e: Exception) { - e.printStackTrace() + (unitReportsViewModel.report.value as? ReportController.Report.XlsxReport)?.let { report -> + it?.data?.data?.also { uri -> + Log.d("UnitReportsFragment", "Downloading file into ${uri.path}") + val outputStream = context?.contentResolver?.openOutputStream(uri) + outputStream?.let { + try { + outputStream.write(report.data) + outputStream.flush() + outputStream.close() + Log.d("UnitReportsFragment", "Wrote file into ${uri.path}") + } catch (e: Exception) { + e.printStackTrace() + } } } } 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 fe13ba0..865f096 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 @@ -1,58 +1,31 @@ package mx.trackermap.TrackerMap.android.details.reports -import android.util.Log import androidx.lifecycle.* import kotlinx.coroutines.DelicateCoroutinesApi -import java.text.SimpleDateFormat import kotlinx.coroutines.flow.collect import kotlinx.coroutines.launch -import mx.trackermap.TrackerMap.client.apis.ReportsApi -import mx.trackermap.TrackerMap.client.models.* -import mx.trackermap.TrackerMap.controllers.GeofencesController +import mx.trackermap.TrackerMap.controllers.ReportController +import mx.trackermap.TrackerMap.utils.ReportDates import org.koin.core.component.KoinComponent import org.koin.core.component.inject -import java.util.* -import java.util.Calendar @DelicateCoroutinesApi class UnitReportsViewModel( - private val reportsApi: ReportsApi, savedStateHandle: SavedStateHandle ) : ViewModel(), KoinComponent { - sealed class Report { - class PositionsReport(val positions: Array) : Report() - class EventsReport(val events: Array) : Report() - class StopsReport(val stops: Array) : Report() - object LoadingReport: Report() - } - - enum class ReportType { - POSITIONS, EVENTS, STOPS - } - - enum class ReportPeriod { - DAY, WEEK, MONTH - } - - private val geofenceController: GeofencesController by inject() + private val reportController: ReportController by inject() private var _deviceId = savedStateHandle.getLiveData("deviceId", 0) - private val _reportType: MutableLiveData = savedStateHandle.getLiveData("reportType", null) - private val _reportPeriod: MutableLiveData = + private val _reportType: MutableLiveData = savedStateHandle.getLiveData("reportType", null) + private val _reportPeriod: MutableLiveData = savedStateHandle.getLiveData("reportPeriod", null) - private val _report: MutableLiveData = MutableLiveData() - private val _reportFile: MutableLiveData = MutableLiveData() - private val _geofences: MutableLiveData> = MutableLiveData() + private val _report: MutableLiveData = MutableLiveData() val deviceId: LiveData get() = _deviceId - val reportType: LiveData get() = _reportType - val reportPeriod: LiveData get() = _reportPeriod - val report: LiveData get() = _report - val reportFile: LiveData get() = _reportFile - val geofences: LiveData> get() = _geofences - - private val dateFormat = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.getDefault()) + val reportType: LiveData get() = _reportType + val reportPeriod: LiveData get() = _reportPeriod + val report: LiveData get() = _report init { viewModelScope.launch { @@ -62,7 +35,7 @@ class UnitReportsViewModel( setupPeriodObserver() } viewModelScope.launch { - setupGeofenceObserver() + setupReportObserver() } } @@ -78,9 +51,9 @@ class UnitReportsViewModel( } } - private suspend fun setupGeofenceObserver() { - geofenceController.geofencesFlow.collect { - _geofences.postValue(it) + private suspend fun setupReportObserver() { + reportController.reportFlow.collect { + _report.value = it } } @@ -88,32 +61,14 @@ class UnitReportsViewModel( _deviceId.value = id } - fun setReportType(reportType: ReportType) { + fun setReportType(reportType: ReportController.ReportType) { _reportType.value = reportType } - fun setReportPeriod(reportPeriod: ReportPeriod) { + fun setReportPeriod(reportPeriod: ReportDates.ReportPeriod) { _reportPeriod.value = reportPeriod } - fun getGeofence(id: Int): Geofence? = _geofences.value?.get(id) - - private fun getDates(): Pair { - val calendar = Calendar.getInstance() - val currentDate = calendar.time - - calendar.add( - Calendar.DATE, when (_reportPeriod.value!!) { - ReportPeriod.DAY -> -1 - ReportPeriod.WEEK -> -7 - ReportPeriod.MONTH -> -30 - } - ) - val previousDate = calendar.time - - return Pair(currentDate, previousDate) - } - fun fetchReportXlsx() { fetchReport(true) } @@ -123,105 +78,15 @@ class UnitReportsViewModel( return } - val (currentDate, previousDate) = getDates() - Log.d("UnitReportsVM", "Current report type: ${_reportType.value.toString()}") - Log.d("UnitReportsVM", "Current report period: ${_reportPeriod.value.toString()}") - Log.d("UnitReportsVM", "Current date:${dateFormat.format(currentDate)}") - Log.d("UnitReportsVM", "Previous date:${dateFormat.format(previousDate)}") - - if (!xlsx) { - _report.postValue(Report.LoadingReport) - } viewModelScope.launch { - when (_reportType.value!!) { - 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, xlsx: Boolean) { - Log.d("UnitReportsVM", "Fetching positions") - - 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") - _reportFile.postValue(result) - } - - } - - private suspend fun fetchEvents(from: Date, to: Date, xlsx: Boolean) { - Log.d("UnitReportsVM", "Fetching events") - - 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() - - eventsResult.forEach { event -> - result.add(EventInformation( - event = event, - position = positionsResult.find { it.id == event.positionId } - )) + _deviceId.value?.let { id -> + reportController.fetchReport( + deviceId = id, + reportType = _reportType.value, + reportPeriod = _reportPeriod.value, + xlsx = xlsx + ) } - - 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") - _reportFile.postValue(result) - } - } - - private suspend fun fetchStops(from: Date, to: Date, xlsx: Boolean) { - Log.d("UnitReportsVM", "Fetching stops") - - 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") - _reportFile.postValue(result) } - } } \ No newline at end of file diff --git a/androidApp/src/main/res/menu/report_period_options.xml b/androidApp/src/main/res/menu/report_period_options.xml index cf54ec3..60fb58c 100644 --- a/androidApp/src/main/res/menu/report_period_options.xml +++ b/androidApp/src/main/res/menu/report_period_options.xml @@ -3,15 +3,31 @@ xmlns:android="http://schemas.android.com/apk/res/android"> + android:id="@+id/optionToday" + android:title="@string/period_today" /> + android:id="@+id/optionLast24" + android:title="@string/period_last_24" /> + android:id="@+id/optionYesterday" + android:title="@string/period_yesterday" /> + + + + + + + + \ No newline at end of file diff --git a/androidApp/src/main/res/values-es-rMX/strings.xml b/androidApp/src/main/res/values-es-rMX/strings.xml index 1916f26..7ebf7d2 100644 --- a/androidApp/src/main/res/values-es-rMX/strings.xml +++ b/androidApp/src/main/res/values-es-rMX/strings.xml @@ -81,13 +81,19 @@ Posiciones Eventos Paradas - Día - Semana - Mes Periodo Seleccionar Exportar + + Hoy + Últimas 24H + Ayer + Semana + Últimos 7d + Mes + Últimos 30d + Evento Fecha y hora Geocerca diff --git a/androidApp/src/main/res/values/strings.xml b/androidApp/src/main/res/values/strings.xml index e3a31e0..5f9714e 100644 --- a/androidApp/src/main/res/values/strings.xml +++ b/androidApp/src/main/res/values/strings.xml @@ -104,13 +104,19 @@ Positions Events Stops - Day - Week - Month Period Select Export + + Today + Last 24H + Yesterday + Week + Last 7d + Month + Last 30d + Event Datetime Geofence -- cgit v1.2.3