Intégration fonctionnalites V1

This commit is contained in:
bastien
2026-07-04 22:30:18 +02:00
parent 55a558b536
commit 10ee859602
54 changed files with 4802 additions and 1018 deletions
+113 -23
View File
@@ -3,6 +3,7 @@
namespace App\Services;
use App\Models\Booking;
use App\Models\Establishment;
use App\Models\Machine;
use App\Models\MachineEvent;
use App\Models\Supervisor;
@@ -15,14 +16,14 @@ class DashboardService
/**
* @return array<string, mixed>
*/
public function getKpis(Supervisor $supervisor): array
public function getKpis(Supervisor $supervisor, ?int $establishmentFilter = null): array
{
$offlineThresholdMinutes = (int) config('laverie.machine.offline_threshold_minutes', 10);
$today = Carbon::today();
$washQuery = $this->washQuery($supervisor)->whereDate('started_at', $today);
$bookingQuery = $this->bookingQuery($supervisor)->whereDate('slot_start', $today);
$machineQuery = $this->machineQuery($supervisor);
$washQuery = $this->washQuery($supervisor, $establishmentFilter)->whereDate('started_at', $today);
$bookingQuery = $this->bookingQuery($supervisor, $establishmentFilter)->whereDate('slot_start', $today);
$machineQuery = $this->machineQuery($supervisor, $establishmentFilter);
$offlineThreshold = now()->subMinutes($offlineThresholdMinutes);
@@ -36,6 +37,8 @@ class DashboardService
})
->count();
$machinesTotal = (clone $machineQuery)->count();
return [
'revenue_today' => (float) (clone $washQuery)
->where('status', 'completed')
@@ -43,16 +46,85 @@ class DashboardService
'washes_today' => (clone $washQuery)->count(),
'bookings_today' => (clone $bookingQuery)->count(),
'offline_machines' => $offlineCount,
'machines_total' => (clone $machineQuery)->count(),
'machines_total' => $machinesTotal,
'running_machines' => (clone $machineQuery)->where('status', 'running')->count(),
'available_machines' => (clone $machineQuery)->where('status', 'available')->count(),
'active_bookings' => $this->bookingQuery($supervisor, $establishmentFilter)
->whereIn('status', ['confirmed', 'active'])
->where('slot_end', '>=', now())
->count(),
];
}
/**
* @return array<string, int>
*/
public function getMachineStatusBreakdown(Supervisor $supervisor, ?int $establishmentFilter = null): array
{
$statuses = ['available', 'reserved', 'running', 'maintenance', 'offline', 'error'];
$counts = $this->machineQuery($supervisor, $establishmentFilter)
->selectRaw('status, COUNT(*) as count')
->groupBy('status')
->pluck('count', 'status');
$breakdown = [];
foreach ($statuses as $status) {
$breakdown[$status] = (int) ($counts[$status] ?? 0);
}
return $breakdown;
}
/**
* @return Collection<int, array<string, mixed>>
*/
public function getRecentWashes(Supervisor $supervisor, ?int $establishmentFilter = null, int $limit = 5): Collection
{
return $this->washQuery($supervisor, $establishmentFilter)
->with(['machine:id,name,uuid', 'machine.establishment:id,name'])
->orderByDesc('started_at')
->limit($limit)
->get()
->map(fn (Wash $wash) => [
'uuid' => $wash->uuid,
'machine_name' => $wash->machine?->name ?? '—',
'establishment_name' => $wash->machine?->establishment?->name,
'status' => $wash->status,
'status_label' => $this->washStatusLabel($wash->status),
'cost' => (float) $wash->cost,
'started_at' => $wash->started_at?->toIso8601String(),
]);
}
/**
* @return array<string, string|null>
*/
public function getContext(Supervisor $supervisor, ?int $establishmentFilter = null): array
{
$supervisor->loadMissing(['organization:id,name', 'establishment:id,name']);
$establishmentName = $supervisor->establishment?->name;
if ($establishmentName === null && $establishmentFilter !== null) {
$establishmentName = Establishment::query()
->where('id', $establishmentFilter)
->where('organization_id', $supervisor->organization_id)
->value('name');
}
return [
'organization_name' => $supervisor->organization?->name,
'establishment_name' => $establishmentName,
'is_all_establishments' => $supervisor->establishment_id === null && $establishmentFilter === null,
];
}
/**
* @return Collection<int, array<string, mixed>>
*/
public function getAlerts(Supervisor $supervisor, int $limit = 10): Collection
public function getAlerts(Supervisor $supervisor, ?int $establishmentFilter = null, int $limit = 10): Collection
{
$machineIds = $this->machineQuery($supervisor)->pluck('id');
$machineIds = $this->machineQuery($supervisor, $establishmentFilter)->pluck('id');
if ($machineIds->isEmpty()) {
return collect();
@@ -104,9 +176,9 @@ class DashboardService
/**
* @return Collection<int, array<string, mixed>>
*/
public function getMachinesOverview(Supervisor $supervisor): Collection
public function getMachinesOverview(Supervisor $supervisor, ?int $establishmentFilter = null): Collection
{
return $this->machineQuery($supervisor)
return $this->machineQuery($supervisor, $establishmentFilter)
->with('establishment:id,name')
->orderBy('name')
->limit(12)
@@ -123,41 +195,47 @@ class DashboardService
]);
}
private function machineQuery(Supervisor $supervisor)
private function machineQuery(Supervisor $supervisor, ?int $establishmentFilter = null)
{
$query = Machine::query()->whereHas('establishment', function ($query) use ($supervisor) {
$establishmentId = $supervisor->establishment_id ?? $establishmentFilter;
$query = Machine::query()->whereHas('establishment', function ($query) use ($supervisor, $establishmentId) {
$query->where('organization_id', $supervisor->organization_id);
if ($supervisor->establishment_id !== null) {
$query->where('id', $supervisor->establishment_id);
if ($establishmentId !== null) {
$query->where('id', $establishmentId);
}
});
if ($supervisor->establishment_id !== null) {
$query->where('establishment_id', $supervisor->establishment_id);
if ($establishmentId !== null) {
$query->where('establishment_id', $establishmentId);
}
return $query;
}
private function washQuery(Supervisor $supervisor)
private function washQuery(Supervisor $supervisor, ?int $establishmentFilter = null)
{
return Wash::query()->whereHas('machine.establishment', function ($query) use ($supervisor) {
$establishmentId = $supervisor->establishment_id ?? $establishmentFilter;
return Wash::query()->whereHas('machine.establishment', function ($query) use ($supervisor, $establishmentId) {
$query->where('organization_id', $supervisor->organization_id);
if ($supervisor->establishment_id !== null) {
$query->where('id', $supervisor->establishment_id);
if ($establishmentId !== null) {
$query->where('id', $establishmentId);
}
});
}
private function bookingQuery(Supervisor $supervisor)
private function bookingQuery(Supervisor $supervisor, ?int $establishmentFilter = null)
{
return Booking::query()->whereHas('machine.establishment', function ($query) use ($supervisor) {
$establishmentId = $supervisor->establishment_id ?? $establishmentFilter;
return Booking::query()->whereHas('machine.establishment', function ($query) use ($supervisor, $establishmentId) {
$query->where('organization_id', $supervisor->organization_id);
if ($supervisor->establishment_id !== null) {
$query->where('id', $supervisor->establishment_id);
if ($establishmentId !== null) {
$query->where('id', $establishmentId);
}
});
}
@@ -195,4 +273,16 @@ class DashboardService
default => $type,
};
}
private function washStatusLabel(string $status): string
{
return match ($status) {
'pending_start' => 'En attente',
'running' => 'En cours',
'completed' => 'Terminé',
'cancelled' => 'Annulé',
'failed' => 'Échoué',
default => $status,
};
}
}