Relatórios
Módulo de relatórios analíticos. Atualmente disponível o relatório de temperatura de sensores por veículo e período, com gráficos interativos (linha, barra, pizza), paginação e exportação em PDF/imagem.
Navegação Interna
O ReportFragment é a tela inicial do módulo — exibe botões de seleção de tipo de relatório. O único relatório disponível atualmente é o de temperatura, acessado via nav_report_temp:
binding.reportTemp.setOnClickListener {
findNavController().navigate(R.id.nav_report_temp)
}
ReportPositionFragment (relatório de posições) está criado mas ainda vazio. ReportViewModel também está em branco. O foco atual é o módulo de temperatura.
Relatório de Temperatura — ReportTempFragment
Permite selecionar veículo (spinner) e intervalo de datas (MaterialDatePicker) para carregar o histórico de temperaturas de até 3 sensores simultâneos.
Filtros
| Filtro | Componente | Comportamento |
|---|---|---|
| Veículo | Spinner com placas | Populado via ReportTempViewModel.fetchDataFromApi(). Mapa interno plateToIdMap converte placa → vehicle_id. |
| Intervalo de datas | MaterialDatePicker.dateRangePicker() | Seleciona start/end. As datas são convertidas de milissegundos para segundos (/ 1000) antes de enviar à API. |
Gráficos (MPAndroidChart)
Três abas com gráficos alternados via TabLayout:
| Tab | Gráfico | Dados exibidos |
|---|---|---|
| 0 | LineChart | Temperatura dos 3 sensores ao longo do tempo + linhas de limite (superior vermelho tracejado, inferior azul tracejado) |
| 1 | BarChart | % de tempo DENTRO / FORA / SEM FAIXA da temperatura ideal |
| 2 | PieChart | Distribuição percentual de eficiência (dentro/fora/sem faixa) |
Eficiência Térmica
Cada registro tem o campo eficiencia com os possíveis valores:
| Valor | Significado | Cor nos gráficos |
|---|---|---|
"DENTRO" | Temperatura dentro da faixa ideal | Verde rgb(126, 211, 33) |
"FORA" | Temperatura fora da faixa ideal | Vermelho rgb(251, 76, 76) |
| outros / vazio | Sem faixa configurada | Cinza rgb(170, 170, 170) |
Paginação Infinita
A lista de registros de temperatura usa paginação local de 50 itens por página. Ao rolar até perto do fim do RecyclerView (dentro de 5 items do total), mais itens são carregados da lista em memória:
val pageSize = 50
// Carrega próximos 50 ao detectar scroll perto do fim
if ((visibleItemCount + firstVisibleItemPosition) >= totalItemCount - 5) {
loadMoreData()
}
Exportação
Botão shareButton abre diálogo com duas opções:
| Opção | Formato | Detalhes |
|---|---|---|
| Compartilhar como PDF | application/pdf | Gerado via iText PDF. Inclui: cabeçalho (placa, período), resumo de eficiência e tabela com até 100 registros. Salvo em Environment.DIRECTORY_DOCUMENTS. |
| Compartilhar como Imagem | image/jpeg | Captura do gráfico ativo na tab atual. Salvo em Environment.DIRECTORY_PICTURES. |
Intent.ACTION_SEND com FileProvider. O package_name.fileprovider deve estar declarado no AndroidManifest.xml.
Modelo de Dados (TemperatureData)
data class TemperatureData(
val dataHora: String, // "dd/MM/yyyy, HH:mm:ss"
val temperatura1: Double?, // Sensor 1 (°C) — pode ser null
val temperatura2: Double?, // Sensor 2
val temperatura3: Double?, // Sensor 3
val faixa: String, // "X° à Y°" | "< X°" | "> X°" | "Sem Faixa"
val eficiencia: String, // "DENTRO" | "FORA" | ""
val numeroSM: String // ID da viagem (SM) para agrupar limites
)
Permissões
| Código | Ação |
|---|---|
115 | Acesso ao módulo de Relatórios (controla botão na Home) |
SharedPreferences relevantes
| Nome | Chave | Uso |
|---|---|---|
selected_company | company_id | Empresa ativa — passa como clientId às chamadas de API |
user_id | user_id | ID do usuário autenticado |
credentials | token_credential | Token legado usado nas chamadas do ReportTempViewModel |