@extends('reports.pdf.layout') @section('title', $data['meta']['title']) @php $meta = $data['meta']; $kpis = $data['kpis']; $weekly = $data['weekly']; $types = $data['types']; $monthly = $data['monthly']; $fmtNum = function ($v, $unit = '') { if ($v === null) return '—'; $s = is_numeric($v) ? number_format((float) $v, 0, ',', ' ') : (string) $v; return trim($s . ' ' . $unit); }; // Bar geometry. $barW = 320; $barH = 130; $barPadX = 28; $barPadY = 22; $maxWeekly = 0; foreach ($weekly as $r) { $maxWeekly = max($maxWeekly, (int) $r['value']); } $maxWeekly = max($maxWeekly, 1); // Pie geometry. $pieRadius = 50; $pieCx = 60; $pieCy = 60; $totalPie = array_sum(array_column($types, 'value')); $pieSlices = []; $accAngle = -90; foreach ($types as $p) { if ($totalPie <= 0) break; $sweep = ((float) $p['value'] / $totalPie) * 360; if ($sweep <= 0) { $pieSlices[] = ['path' => null, 'color' => $p['color'], 'label' => $p['label'], 'value' => $p['value']]; continue; } $isFull = $sweep >= 359.999; if ($isFull) { $path = null; } else { $rad1 = deg2rad($accAngle); $rad2 = deg2rad($accAngle + $sweep); $x1 = $pieCx + $pieRadius * cos($rad1); $y1 = $pieCy + $pieRadius * sin($rad1); $x2 = $pieCx + $pieRadius * cos($rad2); $y2 = $pieCy + $pieRadius * sin($rad2); $largeArc = $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, $largeArc, $x2, $y2); } $pieSlices[] = ['path' => $path, 'color' => $p['color'], 'label' => $p['label'], 'value' => $p['value']]; $accAngle += $sweep; } // Line chart geometry. $lineW = 480; $lineH = 150; $linePadX = 30; $linePadY = 22; $maxLine = 0; foreach ($monthly as $m) { $maxLine = max($maxLine, (int) $m['reservations'], (int) $m['cancellations']); } $maxLine = max($maxLine, 1); $lineSlot = count($monthly) > 1 ? ($lineW - 2 * $linePadX) / (count($monthly) - 1) : 0; @endphp @section('content')
DADYCAR FLEET MANAGER

{{ $meta['title'] }}

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

Indicateurs clés

Réservations
{{ $fmtNum($kpis['reservations_total']['value']) }}
{{ $kpis['reservations_total']['delta_label'] }}
Taux d'annulation
{{ number_format($kpis['cancellation_rate']['value'], 1, ',', ' ') }}{{ $kpis['cancellation_rate']['unit'] }}
{{ $kpis['cancellation_rate']['delta_label'] }}
Taux de no-show
{{ number_format($kpis['no_show_rate']['value'], 1, ',', ' ') }}{{ $kpis['no_show_rate']['unit'] }}
{{ $kpis['no_show_rate']['delta_label'] }}
Dernière minute
{{ number_format($kpis['last_minute_share']['value'], 1, ',', ' ') }}{{ $kpis['last_minute_share']['unit'] }}
{{ $kpis['last_minute_share']['delta_label'] }}

Volume de réservations par semaine

@php $bc = count($weekly); $bs = $bc > 0 ? ($barW - 2 * $barPadX) / $bc : 0; $bw = $bs * 0.55; @endphp @foreach ($weekly as $i => $r) @php $h = $maxWeekly > 0 ? (($r['value'] / $maxWeekly) * ($barH - 2 * $barPadY)) : 0; $x = $barPadX + $i * $bs + ($bs - $bw) / 2; $y = $barH - $barPadY - $h; @endphp {{ $r['value'] }} {{ $r['label'] }} @endforeach

Types de réservation

@if ($totalPie > 0)
@foreach ($pieSlices as $s) @if ($s['path'] === null) @else @endif @endforeach @foreach ($pieSlices as $s)
{{ $s['label'] }} — {{ $s['value'] }}
@endforeach
@else

Pas de données.

@endif

Évolution mensuelle — réservations vs annulations

@if ($maxLine > 0) @php $prevX1 = null; $prevY1 = null; $prevX2 = null; $prevY2 = null; @endphp @foreach ($monthly as $i => $m) @php $x = $linePadX + $i * $lineSlot; $y1 = $lineH - $linePadY - ($maxLine > 0 ? ($m['reservations'] / $maxLine) * ($lineH - 2 * $linePadY) : 0); $y2 = $lineH - $linePadY - ($maxLine > 0 ? ($m['cancellations'] / $maxLine) * ($lineH - 2 * $linePadY) : 0); @endphp @if ($prevX1 !== null) @endif {{ $m['label'] }} @php $prevX1 = $x; $prevY1 = $y1; $prevX2 = $x; $prevY2 = $y2; @endphp @endforeach
Réservations Annulations
@else

Pas de données.

@endif @endsection