Bläddra i källkod

feat(cli): add attivita filter to fest salute

Co-authored-by: Cursor <cursoragent@cursor.com>
marcofalabretti 2 veckor sedan
förälder
incheckning
1271292c87
1 ändrade filer med 131 tillägg och 10 borttagningar
  1. 131
    10
      app/Console/Commands/FestSalute.php

+ 131
- 10
app/Console/Commands/FestSalute.php Visa fil

@@ -2,6 +2,7 @@
2 2
 
3 3
 namespace App\Console\Commands;
4 4
 
5
+use App\Models\Attivita;
5 6
 use App\Models\Cucina;
6 7
 use App\Models\Dispositivo;
7 8
 use App\Models\Endpoint;
@@ -14,7 +15,7 @@ use Illuminate\Support\Facades\Schema;
14 15
 
15 16
 class FestSalute extends Command
16 17
 {
17
-    protected $signature = 'fest:salute';
18
+    protected $signature = 'fest:salute {--attivita= : ID o slug attività (oppure usa --attivita senza valore per scegliere da elenco)}';
18 19
 
19 20
     protected $description = 'Verifica Redis, code, stampe, endpoint e configurazione cassa/cucina';
20 21
 
@@ -22,11 +23,24 @@ class FestSalute extends Command
22 23
 
23 24
     private int $attenzione = 0;
24 25
 
26
+    private ?int $attivitaIdFiltro = null;
27
+
28
+    private ?string $attivitaLabelFiltro = null;
29
+
25 30
     public function handle(): int
26 31
     {
27 32
         $this->info('Fest — controllo salute');
28 33
         $this->newLine();
29 34
 
35
+        if (! $this->resolveAttivitaFiltro()) {
36
+            return self::FAILURE;
37
+        }
38
+
39
+        if ($this->attivitaIdFiltro !== null) {
40
+            $this->line('<comment>Filtro attività:</comment> #'.$this->attivitaIdFiltro.' '.$this->attivitaLabelFiltro);
41
+            $this->newLine();
42
+        }
43
+
30 44
         $this->checkDatabase();
31 45
         $this->checkMigrazioni();
32 46
         $this->checkRedis();
@@ -170,7 +184,12 @@ class FestSalute extends Command
170 184
     private function checkEndpoint(): void
171 185
     {
172 186
         try {
173
-            $attivi = Endpoint::query()->where('status', Endpoint::ATTIVO)->get();
187
+            $query = Endpoint::query()->where('status', Endpoint::ATTIVO);
188
+            if ($this->attivitaIdFiltro !== null) {
189
+                $query->where('attivita_id', $this->attivitaIdFiltro);
190
+            }
191
+
192
+            $attivi = $query->get();
174 193
             if ($attivi->isEmpty()) {
175 194
                 $this->warnCheck('Endpoint', 'nessun FestAgent attivo: le stampe non escono');
176 195
 
@@ -205,10 +224,15 @@ class FestSalute extends Command
205 224
     private function checkCasse(): void
206 225
     {
207 226
         try {
208
-            $casse = Dispositivo::query()
227
+            $query = Dispositivo::query()
209 228
                 ->whereIn('tipo', [Dispositivo::CASSA, Dispositivo::KIOSK, Dispositivo::CAMERIERE])
210
-                ->where('is_attivo', true)
211
-                ->get();
229
+                ->where('is_attivo', true);
230
+
231
+            if ($this->attivitaIdFiltro !== null) {
232
+                $query->where('attivita_id', $this->attivitaIdFiltro);
233
+            }
234
+
235
+            $casse = $query->get();
212 236
 
213 237
             if ($casse->isEmpty()) {
214 238
                 $this->warnCheck('Casse', 'nessun punto vendita attivo');
@@ -233,7 +257,12 @@ class FestSalute extends Command
233 257
     private function checkCucine(): void
234 258
     {
235 259
         try {
236
-            $cucine = Cucina::query()->where('is_attiva', true)->get();
260
+            $query = Cucina::query()->where('is_attiva', true);
261
+            if ($this->attivitaIdFiltro !== null) {
262
+                $query->where('attivita_id', $this->attivitaIdFiltro);
263
+            }
264
+
265
+            $cucine = $query->get();
237 266
             if ($cucine->isEmpty()) {
238 267
                 $this->warnCheck('Cucine', 'nessuna cucina attiva');
239 268
 
@@ -258,17 +287,40 @@ class FestSalute extends Command
258 287
     {
259 288
         try {
260 289
             $limite = now()->subMinutes(10);
261
-            $inAttesa = PrintJob::query()
290
+            $baseQuery = PrintJob::query()
291
+                ->where('created_at', '<', $limite);
292
+
293
+            if ($this->attivitaIdFiltro !== null) {
294
+                $attivitaId = $this->attivitaIdFiltro;
295
+                $baseQuery->where(function ($query) use ($attivitaId) {
296
+                    $query
297
+                        ->whereHas('ordine', fn ($q) => $q->where('attivita_id', $attivitaId))
298
+                        ->orWhereHas('dispositivo', fn ($q) => $q->where('attivita_id', $attivitaId))
299
+                        ->orWhereHas('stampante', fn ($q) => $q->where('attivita_id', $attivitaId));
300
+                });
301
+            }
302
+
303
+            $inAttesa = (clone $baseQuery)
262 304
                 ->where('stato', PrintJob::STATO_IN_ATTESA)
263
-                ->where('created_at', '<', $limite)
264 305
                 ->count();
265
-            $inCoda = PrintJob::query()
306
+            $inCoda = (clone $baseQuery)
266 307
                 ->where('stato', PrintJob::STATO_IN_CODA)
267
-                ->where('created_at', '<', $limite)
268 308
                 ->count();
269 309
             $fallitiOggi = PrintJob::query()
270 310
                 ->where('stato', PrintJob::STATO_FALLITO)
271 311
                 ->whereDate('created_at', today())
312
+                ->when(
313
+                    $this->attivitaIdFiltro !== null,
314
+                    function ($query) {
315
+                        $attivitaId = $this->attivitaIdFiltro;
316
+                        $query->where(function ($subQuery) use ($attivitaId) {
317
+                            $subQuery
318
+                                ->whereHas('ordine', fn ($q) => $q->where('attivita_id', $attivitaId))
319
+                                ->orWhereHas('dispositivo', fn ($q) => $q->where('attivita_id', $attivitaId))
320
+                                ->orWhereHas('stampante', fn ($q) => $q->where('attivita_id', $attivitaId));
321
+                        });
322
+                    }
323
+                )
272 324
                 ->count();
273 325
 
274 326
             if ($inAttesa > 0 || $inCoda > 0) {
@@ -308,4 +360,73 @@ class FestSalute extends Command
308 360
         $this->attenzione++;
309 361
         $this->line('<comment>[ATTENZIONE]</comment> '.$voce.' — '.$dettaglio);
310 362
     }
363
+
364
+    private function resolveAttivitaFiltro(): bool
365
+    {
366
+        $rawOption = $this->option('attivita');
367
+        $flagAttivitaPresente = $this->input->hasParameterOption('--attivita');
368
+
369
+        if (! $flagAttivitaPresente && ! filled($rawOption)) {
370
+            return true;
371
+        }
372
+
373
+        $attivitaList = Attivita::query()
374
+            ->orderBy('nome')
375
+            ->get(['id', 'nome', 'slug']);
376
+
377
+        if ($attivitaList->isEmpty()) {
378
+            $this->koCheck('Attività', 'nessuna attività disponibile per applicare il filtro');
379
+
380
+            return false;
381
+        }
382
+
383
+        if (filled($rawOption)) {
384
+            $value = trim((string) $rawOption);
385
+            $attivita = is_numeric($value)
386
+                ? $attivitaList->firstWhere('id', (int) $value)
387
+                : $attivitaList->firstWhere('slug', $value);
388
+
389
+            if (! $attivita) {
390
+                $this->koCheck('Attività', "filtro '{$value}' non trovato (usa ID o slug valido)");
391
+
392
+                return false;
393
+            }
394
+
395
+            $this->attivitaIdFiltro = (int) $attivita->id;
396
+            $this->attivitaLabelFiltro = (string) ($attivita->nome ?? ('Attività #'.$attivita->id));
397
+
398
+            return true;
399
+        }
400
+
401
+        if (! $this->input->isInteractive()) {
402
+            $this->koCheck('Attività', 'modalità non interattiva: usa --attivita={id|slug}');
403
+
404
+            return false;
405
+        }
406
+
407
+        $choices = $attivitaList
408
+            ->map(fn (Attivita $attivita) => (string) $attivita->id.' - '.((string) ($attivita->nome ?? 'Attività')).(filled($attivita->slug) ? ' ['.$attivita->slug.']' : ''))
409
+            ->values()
410
+            ->all();
411
+
412
+        $selected = (string) $this->choice('Seleziona attività da analizzare', $choices, 0);
413
+        if (! preg_match('/^(\d+)/', $selected, $match)) {
414
+            $this->koCheck('Attività', 'selezione non valida');
415
+
416
+            return false;
417
+        }
418
+
419
+        $selectedId = (int) $match[1];
420
+        $attivita = $attivitaList->firstWhere('id', $selectedId);
421
+        if (! $attivita) {
422
+            $this->koCheck('Attività', 'attività selezionata non trovata');
423
+
424
+            return false;
425
+        }
426
+
427
+        $this->attivitaIdFiltro = $selectedId;
428
+        $this->attivitaLabelFiltro = (string) ($attivita->nome ?? ('Attività #'.$selectedId));
429
+
430
+        return true;
431
+    }
311 432
 }

Laddar…
Avbryt
Spara