@extends('reports.pdf.layout') @section('title', $data['meta']['title']) @php $meta = $data['meta']; $kpis = $data['kpis']; $series = $data['monthly_series']; $split = $data['internal_external_split']; $top = $data['top_vehicles']; $fmtNum = function ($v, $unit = '') { if ($v === null) return '—'; $s = is_numeric($v) ? number_format((float) $v, 0, ',', ' ') : (string) $v; return trim($s . ' ' . $unit); }; $fmtDelta = function ($v, $unit = '%') { if ($v === null) return null; $sign = $v > 0 ? '+' : ''; return $sign . number_format((float) $v, 1, ',', ' ') . $unit; }; $deltaClass = function ($v, bool $maximize = true) { if ($v === null || $v == 0) return 'delta-flat'; $up = $v > 0; return ($up === $maximize) ? 'delta-up' : 'delta-down'; }; // ── Bar chart (6 months) ───────────────────────────────────────── $chartW = 480; $chartH = 160; $padX = 30; $padY = 20; $vals = array_map(fn ($r) => (float) $r['total'], $series); $maxV = !empty($vals) ? max($vals) : 0; if ($maxV <= 0) { $maxV = 1; } $barCount = count($series); $availW = $chartW - 2 * $padX; $barW = $barCount > 0 ? ($availW / $barCount) * 0.65 : 0; $stepX = $barCount > 0 ? $availW / max($barCount, 1) : 0; // ── Pie geometry — fallback to when a slice is 360°. ─── $pieRadius = 60; $pieCx = 70; $pieCy = 70; $pieColors = ['#3B82F6', '#F59E0B']; $totalPie = array_sum(array_map(fn ($b) => (float) $b['amount'], $split)); $pieSlices = []; $accAngle = -90; foreach ($split as $i => $b) { if ($totalPie <= 0) break; $sweep = ((float) $b['amount'] / $totalPie) * 360; if ($sweep <= 0) continue; $isFull = $sweep >= 359.999; if ($isFull) { $path = null; } else { $r1 = deg2rad($accAngle); $r2 = deg2rad($accAngle + $sweep); $x1 = $pieCx + $pieRadius * cos($r1); $y1 = $pieCy + $pieRadius * sin($r1); $x2 = $pieCx + $pieRadius * cos($r2); $y2 = $pieCy + $pieRadius * sin($r2); $large = $sweep > 180 ? 1 : 0; $path = sprintf('M %s %s L %.2f %.2f A %s %s 0 %d 1 %.2f %.2f Z', $pieCx, $pieCy, $x1, $y1, $pieRadius, $pieRadius, $large, $x2, $y2); } $pieSlices[] = [ 'path' => $path, 'color' => $pieColors[$i % count($pieColors)], 'label' => $b['label'], 'amount' => $b['amount'], 'pct' => $b['percent'], ]; $accAngle += $sweep; } @endphp @section('content')
DADYCAR FLEET MANAGER

{{ $meta['title'] }}

Maintenance {{ $meta['code'] }} Période : {{ $meta['period']['label'] }} · {{ $meta['site_label'] }} · {{ $meta['total_vehicles'] }} véhicules · Généré le {{ $meta['generated_at']->locale('fr')->isoFormat('D MMMM YYYY') }}

Indicateurs de coûts

Coût total maintenance
{{ $fmtNum($kpis['total_cost']['value']) }}{{ $kpis['total_cost']['unit'] }}
@if ($kpis['total_cost']['delta'] !== null)
{{ $fmtDelta($kpis['total_cost']['delta']) }} {{ $kpis['total_cost']['delta_label'] }}
@else
{{ $kpis['total_cost']['delta_label'] }}
@endif
Coût moyen / véhicule
{{ $fmtNum($kpis['avg_per_vehicle']['value']) }}{{ $kpis['avg_per_vehicle']['unit'] }}
@if ($kpis['avg_per_vehicle']['delta'] !== null)
{{ $fmtDelta($kpis['avg_per_vehicle']['delta']) }} {{ $kpis['avg_per_vehicle']['delta_label'] }}
@else
{{ $kpis['avg_per_vehicle']['delta_label'] }}
@endif
Interne / externe
{{ $kpis['internal_external']['value'] ?? '—' }}{{ $kpis['internal_external']['unit'] }}
{{ $kpis['internal_external']['delta_label'] }}
Évolution mensuelle
{{ $fmtDelta($kpis['monthly_evolution']['value']) ?? '—' }}
{{ $kpis['monthly_evolution']['delta_label'] }}

Coûts mensuels (6 mois)

@if ($maxV > 0) @foreach ($series as $i => $r) @php $h = ($maxV > 0) ? (($r['total'] / $maxV) * ($chartH - 2 * $padY)) : 0; $cx = $padX + $i * $stepX + $stepX / 2; $bx = $cx - $barW / 2; $by = $chartH - $padY - $h; @endphp {{ $r['label'] }} {{ number_format($r['total'], 0, ',', ' ') }} @endforeach @else

Aucune dépense de maintenance sur la période.

@endif

Répartition interne / externe

@if (!empty($pieSlices) && $totalPie > 0)
@foreach ($pieSlices as $s) @if ($s['path'] === null) @else @endif @endforeach @foreach ($pieSlices as $s)
{{ $s['label'] }} — {{ number_format($s['amount'], 0, ',', ' ') }} € ({{ number_format($s['pct'], 1, ',', ' ') }} %)
@endforeach

Approximation : interne = sans vendor_id, externe = avec vendor_id.

@else

Pas de données pour la répartition.

@endif

Top 10 véhicules par coût

@if (!empty($top)) @foreach ($top as $r) @endforeach
Immat. Modèle OT Coût (€) Part
{{ $r['plate'] }} {{ $r['model'] }} {{ $r['ops'] }} {{ number_format($r['total'], 0, ',', ' ') }} {{ number_format($r['share'], 1, ',', ' ') }} %
@else

Aucun véhicule avec dépenses de maintenance sur la période.

@endif
@endsection