@once @endonce
@php $cards = $dashboard['cards']; $visibleCards = \App\Support\DashboardTorreCards::visibleMap(); $isVisible = fn (string $key): bool => $visibleCards[$key] ?? true; $dataInicioLabel = \Illuminate\Support\Carbon::parse($filters['data_inicio'])->format('d/m/Y'); $dataFimLabel = \Illuminate\Support\Carbon::parse($filters['data_fim'])->format('d/m/Y'); $dataLabel = $filters['data_inicio'] === $filters['data_fim'] ? $dataInicioLabel : $dataInicioLabel . ' a ' . $dataFimLabel; $progress = function (int $done, int $total): int { return $total > 0 ? min(100, (int) round(($done / $total) * 100)) : 0; }; $format = fn (int|float $value): string => number_format((float) $value, 0, ',', '.'); $filterQuery = array_filter([ 'data' => $filters['data_inicio'], 'filial_id' => $filters['filial_id'], ], fn ($value) => filled($value)); $controleUrl = \App\Filament\Pages\ControleOperacoes::getUrl() . ($filterQuery ? '?' . http_build_query($filterQuery) : ''); $movimentosPorCidade = $dashboard['movimentos_por_cidade'] ?? []; $maiorVolumeCidade = max(array_column($movimentosPorCidade, 'total') ?: [0]); $ocorrenciasPorMotivo = $dashboard['ocorrencias_por_motivo'] ?? []; $maiorVolumeOcorrencia = max(array_column($ocorrenciasPorMotivo, 'total') ?: [0]); $movimentos = $dashboard['movimentos'] ?? ['abertos' => 0, 'concluidos' => 0, 'ocorrencias' => 0, 'em_rota' => 0, 'total' => 0]; $movimentosAgendados = $dashboard['movimentos_agendados'] ?? ['abertos' => 0, 'concluidos' => 0, 'ocorrencias' => 0, 'em_rota' => 0, 'total' => 0]; $pieSlices = function (array $data): array { return [ ['label' => 'Em aberto', 'value' => (int) ($data['abertos'] ?? 0), 'color' => '#f59e0b'], ['label' => 'Concluidos', 'value' => (int) ($data['concluidos'] ?? 0), 'color' => '#22c55e'], ['label' => 'Ocorrencias', 'value' => (int) ($data['ocorrencias'] ?? 0), 'color' => '#ef4444'], ['label' => 'Em rota', 'value' => (int) ($data['em_rota'] ?? 0), 'color' => '#3b82f6'], ]; }; $pieStyle = function (array $slices): string { $total = max(array_sum(array_column($slices, 'value')), 0); if ($total === 0) { return 'background:#e5e7eb;'; } $cursor = 0; $parts = []; foreach ($slices as $slice) { $start = $cursor; $cursor += (($slice['value'] / $total) * 100); $parts[] = $slice['color'].' '.$start.'% '.$cursor.'%'; } return 'background:conic-gradient('.implode(', ', $parts).');'; }; $movimentosSlices = $pieSlices($movimentos); $agendadosSlices = $pieSlices($movimentosAgendados); $movimentosPieTotal = array_sum(array_column($movimentosSlices, 'value')); $agendadosPieTotal = array_sum(array_column($agendadosSlices, 'value')); $evolucaoPct = $progress((int) ($movimentos['concluidos'] ?? 0), max((int) ($movimentos['total'] ?? 0), 0)); $gaugeRotation = -90 + (180 * ($evolucaoPct / 100)); $topCards = [ [ 'key' => 'entregas', 'label' => 'Entregas', 'value' => $cards['entregas'], 'done' => $cards['entregas_executadas'], 'total' => $cards['entregas'], 'caption' => 'enderecos atendidos', 'progress_text' => $format($cards['entregas_executadas']).'/'.$format($cards['entregas']).' entregues', 'tone' => 'blue', 'icon' => 'ENT', ], [ 'key' => 'coletas', 'label' => 'Coletas', 'value' => $cards['coletas'], 'done' => $cards['coletas_executadas'], 'total' => $cards['coletas'], 'caption' => 'coletas executadas', 'progress_text' => $format($cards['coletas_executadas']).'/'.$format($cards['coletas']).' coletadas', 'tone' => 'green', 'icon' => 'COL', ], [ 'key' => 'transferencias', 'label' => 'Transferencias', 'value' => $cards['transferencias'], 'done' => $cards['transferencias_concluidas'], 'total' => $cards['transferencias'], 'caption' => 'movimento entre filiais', 'progress_text' => $format($cards['transferencias_concluidas']).'/'.$format($cards['transferencias']).' concluidas', 'tone' => 'purple', 'icon' => 'TRA', ], [ 'key' => 'reentregas', 'label' => 'Reentregas', 'value' => $cards['reentregas'], 'done' => $cards['reentregas_concluidas'], 'total' => $cards['reentregas'], 'caption' => 'tentativas pendentes', 'progress_text' => $format($cards['reentregas_concluidas']).'/'.$format($cards['reentregas']).' concluidas', 'tone' => 'red', 'icon' => 'REE', ], [ 'key' => 'ocorrencias', 'label' => 'Ocorrencias', 'value' => max($cards['ocorrencias_total'] - $cards['ocorrencias_tratadas'], 0), 'done' => $cards['ocorrencias_tratadas'], 'total' => $cards['ocorrencias_total'], 'caption' => 'tratadas / a tratar', 'tone' => 'yellow', 'icon' => 'OCO', 'secondary' => $cards['ocorrencias_tratadas'].' / '.max($cards['ocorrencias_total'] - $cards['ocorrencias_tratadas'], 0), ], ]; $bottomCards = [ [ 'key' => 'app_acessos', 'label' => 'Acessos ao aplicativo', 'value' => $cards['motoristas_app'], 'done' => $cards['motoristas_app'], 'total' => $cards['motoristas_operacionais'], 'caption' => 'acesso pelo aplicativo', 'tone' => 'blue', 'icon' => 'APP', ], [ 'key' => 'veiculos_rota', 'label' => 'Veiculos em rota', 'value' => $cards['veiculos_em_rota'], 'done' => $cards['veiculos_em_rota_concluidos'], 'total' => $cards['veiculos_em_rota_total_movimentos'], 'caption' => 'romaneios em rota', 'tone' => 'gray', 'icon' => 'VEI', ], [ 'key' => 'entregas_rota', 'label' => 'Entregas por rota', 'value' => $cards['media_entregas_por_rota'], 'done' => $cards['entregas_por_rota_concluidas'], 'total' => $cards['entregas_por_rota_total'], 'caption' => 'media por veiculo', 'tone' => 'purple', 'icon' => 'ROT', ], [ 'key' => 'custo_viagem', 'label' => 'Custo por viagem', 'value' => 'R$ '.number_format((float) $cards['custo_medio_por_viagem'], 2, ',', '.'), 'done' => (int) round((float) $cards['custo_viagens_total'] * 100), 'total' => max((int) round((float) $cards['custo_viagens_total'] * 100), 1), 'caption' => 'media estimada de custo', 'tone' => 'yellow', 'icon' => 'CUS', ], [ 'key' => 'eficiencia', 'label' => 'Eficiencia da operacao', 'value' => $progress($cards['eficiencia_concluidos'], $cards['eficiencia_total']).'%', 'done' => $cards['eficiencia_concluidos'], 'total' => $cards['eficiencia_total'], 'caption' => 'movimentos concluidos', 'tone' => 'green', 'icon' => 'EFI', ], [ 'key' => 'otif', 'label' => 'OTIF', 'value' => $progress($cards['otif_concluidos'], $cards['otif_total']).'%', 'done' => $cards['otif_concluidos'], 'total' => $cards['otif_total'], 'caption' => 'entregas completas no prazo', 'progress_text' => $format($cards['otif_concluidos']).'/'.$format($cards['otif_total']).' entregas OTIF', 'tone' => 'green', 'icon' => 'OTF', ], [ 'key' => 'entregas_fora_prazo', 'label' => 'Entregas fora do prazo', 'value' => $cards['otif_fora_prazo'], 'done' => $cards['otif_fora_prazo'], 'total' => $cards['otif_entregues'], 'caption' => 'entregas concluidas com atraso', 'progress_text' => $format($cards['otif_fora_prazo']).'/'.$format($cards['otif_entregues']).' entregas fora do prazo', 'tone' => 'red', 'icon' => 'ATR', ], ]; $topCards = collect($topCards) ->filter(fn (array $card): bool => $isVisible($card['key'])) ->values(); $bottomCards = collect($bottomCards) ->filter(fn (array $card): bool => $isVisible($card['key'])) ->values(); $displayCards = $topCards->concat($bottomCards)->values(); @endphp
@svg('heroicon-o-truck', 'fi-icon fi-size-sm', ['style' => 'width:18px;height:18px;margin-right:7px;']) Operações
Atualiza em 03:00
@foreach($displayCards as $card) @php $pct = $progress($card['done'], $card['total']); @endphp
{{ $card['icon'] }}
{{ $card['label'] }} {{ $dataLabel }}
{{ $card['secondary'] ?? (is_numeric($card['value']) ? $format($card['value']) : $card['value']) }}
{{ $card['progress_text'] ?? $card['caption'] }} {{ $pct }}%
@endforeach
Movimentos NFs, coletas, reentregas e transferencias
{{ $format($movimentosPieTotal) }}
{{ $format($movimentosPieTotal) }}
@foreach($movimentosSlices as $slice)
{{ $slice['label'] }} {{ $format($slice['value']) }}
@endforeach
Evolucao operacional Movimentos ja concluidos
{{ $evolucaoPct }}%
{{ $evolucaoPct }}% {{ $format($movimentos['concluidos'] ?? 0) }} concluidos
Agendados Movimentos com data e hora de entrega
{{ $format($agendadosPieTotal) }}
{{ $format($agendadosPieTotal) }}
@foreach($agendadosSlices as $slice)
{{ $slice['label'] }} {{ $format($slice['value']) }}
@endforeach
Ocorrencias pontuadas Quantidade por motivo de ocorrencia e codigo do cliente
{{ $format(array_sum(array_column($ocorrenciasPorMotivo, 'total'))) }}
@if(count($ocorrenciasPorMotivo))
@foreach($ocorrenciasPorMotivo as $ocorrencia) @php $pctOcorrencia = $maiorVolumeOcorrencia > 0 ? max(8, (int) round(($ocorrencia['total'] / $maiorVolumeOcorrencia) * 100)) : 0; @endphp
{{ $format($ocorrencia['total']) }}
{{ $ocorrencia['motivo'] }} {{ $ocorrencia['codigo_cliente'] }}
@endforeach
@else
Sem ocorrencias pontuadas no periodo selecionado.
@endif
Movimentos por regiao Volume de entregas, coletas, reentregas e transferencias por cidade
{{ $dataLabel }}
@forelse($movimentosPorCidade as $cidade) @php $pctCidade = $maiorVolumeCidade > 0 ? max(4, (int) round(($cidade['total'] / $maiorVolumeCidade) * 100)) : 0; @endphp
{{ $cidade['cidade'] }} {{ $cidade['uf'] }}
{{ $format($cidade['total']) }}
@empty
Sem movimentos no periodo selecionado.
@endforelse
@once @endonce