Compare commits

...

5 Commits

Author SHA1 Message Date
Emanuele Slusarz 9a8acb16fd Prima di CODEX 2026-08-23 23:37:26 +02:00
Emanuele Slusarz 57abac80bd Aggiornamento PERSONALE 2026-08-23 15:34:23 +02:00
Emanuele Slusarz a121224899 Aggiornamento lato PERSONALE 2026-08-22 19:53:41 +02:00
Emanuele Slusarz 42979685fb Aggiornamento lato PERSONALE 2026-08-22 16:38:17 +02:00
Emanuele Slusarz c796788339 Aggiornamento lato UTENTE 2026-08-22 15:15:55 +02:00
10 changed files with 1525 additions and 280 deletions
+59 -14
View File
@@ -26,10 +26,10 @@ $comuni = $stmt->fetchAll(PDO::FETCH_ASSOC);
if (postMethod()) { if (postMethod()) {
try {
switch($azione) { switch($azione) {
case "predefinito": { case "predefinito": { // OKOKFATTO
try {
if (!$idIndirizzo) { if (!$idIndirizzo) {
$messaggio = "Id indirizzo non valido"; $messaggio = "Id indirizzo non valido";
die("Id indirizzo non valido"); die("Id indirizzo non valido");
@@ -62,9 +62,23 @@ if (postMethod()) {
$pdo->commit(); $pdo->commit();
break; break;
} catch (PDOException $e) {
if ($pdo -> inTransaction()) {
$pdo->rollBack();
} }
case "inserisci": { $messaggio =
"Errore durante l'aggiornamento dell'indirizzo" .
$e->getMessage();
break;
}
}
case "inserisci": { // OKOKFATTO
try {
if ( if (
$via === "" || $via === "" ||
$numeroCivico === "" || $numeroCivico === "" ||
@@ -74,6 +88,13 @@ if (postMethod()) {
die("Compila i campi correttamente"); die("Compila i campi correttamente");
} }
/*
Verifica della presenza di indirizzi
già registrati a nome del cliente.
Questa operazione non richiede che
sia inserita nella beginTransaction()
*/
$stmt = $pdo->prepare(" $stmt = $pdo->prepare("
SELECT EXISTS ( SELECT EXISTS (
SELECT 1 SELECT 1
@@ -93,6 +114,10 @@ if (postMethod()) {
$predefinito = 1; $predefinito = 1;
} }
/*
Inizia la transazione,
si inserisce nel database la via.
*/
$pdo->beginTransaction(); $pdo->beginTransaction();
$stmt = $pdo->prepare(" $stmt = $pdo->prepare("
INSERT INTO indirizzo (via, numeroCivico, predefinito, idComune, idCliente) INSERT INTO indirizzo (via, numeroCivico, predefinito, idComune, idCliente)
@@ -105,11 +130,28 @@ if (postMethod()) {
"idComune" => $idComune, "idComune" => $idComune,
"idCliente" => $idCliente "idCliente" => $idCliente
]); ]);
$pdo->commit(); $pdo->commit();
$messaggio = "Indirizzo aggiunto con successo";
break; break;
} catch (PDOException $e) {
if ($pdo -> inTransaction()) {
$pdo->rollBack();
} }
case "elimina": { $messaggio =
"Errore durante l'inserimento dell'indirizzo" .
$e->getMessage();
break;
}
}
case "elimina": { // OKOKFATTO
try {
if (!$idIndirizzo) { if (!$idIndirizzo) {
$messaggio = "Id indirizzo non valido"; $messaggio = "Id indirizzo non valido";
die("Id indirizzo non valido"); die("Id indirizzo non valido");
@@ -131,6 +173,18 @@ if (postMethod()) {
$messaggio = "Indirizzo eliminato con successo"; $messaggio = "Indirizzo eliminato con successo";
break; break;
} catch (PDOException $e) {
if ($pdo -> inTransaction()) {
$pdo->rollBack();
}
$messaggio =
"Errore durante l'eliminazione dell'indirizzo" .
$e->getMessage();
break;
}
} }
default: default:
@@ -138,15 +192,6 @@ if (postMethod()) {
break; break;
} }
} catch (PDOException $e) {
if ($pdo->inTransaction()) {
$pdo->rollBack();
}
die(
"Errore durante l'aggiunta dell'indirizzo di consegna: "
. $e->getMessage()
);
}
} }
$stmt = $pdo->prepare(" $stmt = $pdo->prepare("
+13 -4
View File
@@ -24,7 +24,10 @@ $pageTitle = "Menu"; $basePath = "..";
require __DIR__ . "/../includes/header.php"; require __DIR__ . "/../includes/header.php";
?> ?>
<div class="d-flex justify-content-between align-items-center mb-3"> <div class="d-flex justify-content-between align-items-center mb-3">
<div><h1 class="h3 mb-1">Menu</h1><p class="text-muted mb-0">Prodotti disponibili e personalizzazioni.</p></div> <div>
<h1 class="h3 mb-1">Menu</h1>
<p class="text-muted mb-0">Prodotti disponibili e personalizzazioni.</p>
</div>
<a class="btn btn-primary" href="ordine.php">Componi ordine</a> <a class="btn btn-primary" href="ordine.php">Componi ordine</a>
</div> </div>
<?php if (!$prodotti): ?> <?php if (!$prodotti): ?>
@@ -32,15 +35,21 @@ require __DIR__ . "/../includes/header.php";
<?php endif; ?> <?php endif; ?>
<div class="row g-3"> <div class="row g-3">
<?php foreach ($prodotti as $prodotto): ?> <?php foreach ($prodotti as $prodotto): ?>
<div class="col-md-6"><div class="card h-100 shadow-sm"><div class="card-body"> <div class="col-md-6">
<div class="card h-100 shadow-sm">
<div class="card-body">
<h2 class="h5"><?= e($prodotto["nome"] ?? "") ?></h2> <h2 class="h5"><?= e($prodotto["nome"] ?? "") ?></h2>
<p><?= e($prodotto["descrizione"] ?? "") ?></p> <p><?= e($prodotto["descrizione"] ?? "") ?></p>
<span class="badge bg-primary">€ <?= e(number_format((float) ($prodotto["prezzoBase"] ?? 0), 2, ",", ".")) ?></span> <span class="badge bg-primary">€ <?= e(number_format((float) ($prodotto["prezzoBase"] ?? 0), 2, ",", ".")) ?></span>
<?php if (!empty($prodotto["nomeCaratteristica"])): ?> <?php if (!empty($prodotto["nomeCaratteristica"])): ?>
<hr><strong>Caratteristica:</strong> <?= e($prodotto["nomeCaratteristica"]) ?> <hr>
<strong>Caratteristica:</strong>
<?= e($prodotto["nomeCaratteristica"]) ?>
(+ € <?= e($prodotto["differenzaPrezzo"] ?? 0) ?>) (+ € <?= e($prodotto["differenzaPrezzo"] ?? 0) ?>)
<?php endif; ?> <?php endif; ?>
</div></div></div> </div>
</div>
</div>
<?php endforeach; ?> <?php endforeach; ?>
</div> </div>
<?php require __DIR__ . "/../includes/footer.php"; ?> <?php require __DIR__ . "/../includes/footer.php"; ?>
-3
View File
@@ -47,9 +47,6 @@
]); ]);
$ordini = $stmt->fetchAll(PDO::FETCH_ASSOC); $ordini = $stmt->fetchAll(PDO::FETCH_ASSOC);
/* TODO SQL DI SUPPORTO - Elenco e stato degli ordini del cliente.
* Input: $idCliente. Output: idOrdine, dataOraCreazione, statoConferma,
* orarioConsegna, totale, tempoStimatoConsegna, nomeStato. */
$pageTitle = "I miei ordini"; $basePath = ".."; $pageTitle = "I miei ordini"; $basePath = "..";
require __DIR__ . "/../includes/header.php"; require __DIR__ . "/../includes/header.php";
?> ?>
+66 -14
View File
@@ -26,6 +26,7 @@
$prodotti = []; // CARICATO $prodotti = []; // CARICATO
$caratteristicheDisponibili = []; // CARICATO $caratteristicheDisponibili = []; // CARICATO
$indirizzi = []; // CARICATO $indirizzi = []; // CARICATO
$indirizzoPredefinito = null; // CARICATO
$righeOrdine = []; // CARICATO $righeOrdine = []; // CARICATO
$riepilogo = null; // CARICATO $riepilogo = null; // CARICATO
@@ -51,6 +52,29 @@
$indirizzi = $stmt->fetchAll(PDO::FETCH_ASSOC); $indirizzi = $stmt->fetchAll(PDO::FETCH_ASSOC);
$stmt = $pdo->prepare("
SELECT
indirizzo.idIndirizzo,
indirizzo.via,
indirizzo.numeroCivico,
indirizzo.predefinito,
indirizzo.idComune
FROM
indirizzo
WHERE
indirizzo.idCliente = :idCliente
AND indirizzo.predefinito = 1
LIMIT 1
");
$stmt->execute([
"idCliente" => $idCliente
]);
$indirizzoPredefinito = $stmt->fetch(PDO::FETCH_ASSOC);
/* ============================================================ /* ============================================================
* EVENTUALE ORDINE IN BOZZA * EVENTUALE ORDINE IN BOZZA
@@ -580,30 +604,29 @@
"); ");
$stmt->execute([ $stmt->execute([
"idOrdine" => $idOrdine,
"idCliente" => $idCliente,
"totale" => $totale, "totale" => $totale,
"tempoPreparazione" => $tempoPreparazione "tempoPreparazione" => $tempoPreparazione,
"idOrdine" => $idOrdine,
"idCliente" => $idCliente
]); ]);
// Creazione dello storicoStato e statoOrdine
$stmt = $pdo->prepare(" $stmt = $pdo->prepare("
INSERT SELECT
INTO statoOrdine MIN(so1.idStatoOrdine)
(
nomeStato,
posizione
)
VALUES ( FROM
'IN LAVORAZIONE', statoOrdine AS so1
WHERE
so1.nomeStato = 'inserito'
LIMIT
1 1
)
"); ");
$stmt->execute(); $stmt->execute();
$idStatoOrdine = $pdo->lastInsertId(); $idStatoOrdine = $stmt->fetchColumn();
$stmt = $pdo->prepare(" $stmt = $pdo->prepare("
INSERT INSERT
@@ -834,7 +857,36 @@
name="idIndirizzo" name="idIndirizzo"
required required
> >
<?php if ($indirizzoPredefinito === null): ?>
<option value="">Seleziona...</option> <option value="">Seleziona...</option>
<?php endif; ?>
<?php if ($indirizzoPredefinito !== null): ?>
<option
value="<?= e($indirizzoPredefinito["idIndirizzo"]) ?>"
select
>
<?= e($indirizzoPredefinito["via"] . " " . $indirizzoPredefinito["numeroCivico"]) ?>
<?= !empty($indirizzoPredefinito["predefinito"]) ? "(predefinito)" : "" ?>
</option>
<?php endif; ?>
// Rimuovo l'indirizzo dagli indirizzi
<?php
if (
is_array($indirizzoPredefinito) &&
isset($indirizzoPredefinito["idIndirizzo"]) &&
isset($indirizzoPredefinito["via"]) &&
isset($indirizzoPredefinito["numeroCivico"])
) {
foreach ($indirizzi as $key => $i) {
if ($i["idIndirizzo"] == $indirizzoPredefinito["idIndirizzo"]) {
unset($indirizzi[$key]);
break;
}
}
}
?>
<?php foreach ($indirizzi as $i): ?> <?php foreach ($indirizzi as $i): ?>
<option value="<?= e($i["idIndirizzo"]) ?>"> <option value="<?= e($i["idIndirizzo"]) ?>">
+79 -9
View File
@@ -4,17 +4,87 @@ requireRole("personale");
require_once __DIR__ . "/../config/database.php"; require_once __DIR__ . "/../config/database.php";
$idPersonale = (int) $_SESSION["idUtente"]; $idPersonale = (int) $_SESSION["idUtente"];
$conteggi = []; $conteggi = [];
/*
* QUERY 11 - Conteggio degli ordini attivi divisi per stato di avanzamento $stmt = $pdo->prepare("
* Input: nessuno (l'id $idPersonale è disponibile per il contesto UI) SELECT
* Output atteso: idStatoOrdine, nomeStato, posizione, numeroOrdini ss1.idOrdine,
* TODO SQL: implementare manualmente la Query 11. ss1.idStatoOrdine,
*/ so1.nomeStato,
so1.posizione,
conteggioOrdiniPerOrdine.numeroOrdini
FROM
storicoStato AS ss1
JOIN statoOrdine AS so1
ON ss1.idStatoOrdine = so1.idStatoOrdine
LEFT JOIN (
SELECT
o3.idOrdine,
COALESCE(
SUM(ro3.quantita),
0
) AS numeroOrdini
FROM
ordine AS o3
JOIN rigaOrdine AS ro3
ON o3.idOrdine = ro3.idOrdine
GROUP BY
o3.idOrdine
) AS conteggioOrdiniPerOrdine
ON ss1.idOrdine = conteggioOrdiniPerOrdine.idOrdine
WHERE
so1.posizione = (
SELECT
MAX(so2.posizione)
FROM
storicoStato AS ss2
JOIN statoOrdine AS so2
ON ss2.idStatoOrdine = so2.idStatoOrdine
WHERE
ss2.idOrdine = ss1.idOrdine
)
");
$stmt->execute();
$conteggi = $stmt->fetchAll(PDO::FETCH_ASSOC);
$pageTitle = "Dashboard personale"; $basePath = ".."; $pageTitle = "Dashboard personale"; $basePath = "..";
require __DIR__ . "/../includes/header.php"; require __DIR__ . "/../includes/header.php";
?> ?>
<h1 class="h3">Dashboard personale</h1><p>Panoramica degli ordini attivi.</p> <h1 class="h3">Dashboard personale</h1>
<?php if (!$conteggi): ?><div class="alert alert-info">I conteggi saranno mostrati dopo l'implementazione della Query 11.</div><?php endif; ?> <p>Panoramica degli ordini attivi.</p>
<div class="row g-3 mb-4"><?php foreach ($conteggi as $c): ?><div class="col-sm-6 col-lg"><div class="card text-center h-100 shadow-sm"><div class="card-body"><div class="display-6"><?= e($c["numeroOrdini"]) ?></div><div><?= e($c["nomeStato"]) ?></div></div></div></div><?php endforeach; ?></div> <?php if (!$conteggi): ?>
<div class="alert alert-info">Non ci sono ordini!</div>
<?php endif; ?>
<div class="row g-3 mb-4">
<?php foreach ($conteggi as $c): ?>
<div class="col-sm-6 col-lg">
<div class="card text-center h-100 shadow-sm">
<div class="card-body">
<div class="display-6">
<?= "N. Ordini: " . e($c["numeroOrdini"]) ?>
</div>
<div>
<?= "ID Ordine: " . e($c["idOrdine"]) ?>
<br>
<?= "Stato: " . e($c["nomeStato"]) ?>
<br>
<?= "Posizione: " . e($c["posizione"]) ?>
</div>
</div>
</div>
</div>
<?php endforeach; ?></div>
<a class="btn btn-primary" href="ordini.php">Apri gli ordini correnti</a> <a class="btn btn-primary" href="ordini.php">Apri gli ordini correnti</a>
<?php require __DIR__ . "/../includes/footer.php"; ?> <?php require __DIR__ . "/../includes/footer.php"; ?>
+281 -19
View File
@@ -5,29 +5,291 @@ require_once __DIR__ . "/../config/database.php";
$idPersonale = (int) $_SESSION["idUtente"]; $idPersonale = (int) $_SESSION["idUtente"];
$idOrdine = filter_input(INPUT_GET, "idOrdine", FILTER_VALIDATE_INT) ?: filter_input(INPUT_POST, "idOrdine", FILTER_VALIDATE_INT); $idOrdine = filter_input(INPUT_GET, "idOrdine", FILTER_VALIDATE_INT) ?: filter_input(INPUT_POST, "idOrdine", FILTER_VALIDATE_INT);
$idStatoOrdine = filter_input(INPUT_POST, "idStatoOrdine", FILTER_VALIDATE_INT); $idStatoOrdine = filter_input(INPUT_POST, "idStatoOrdine", FILTER_VALIDATE_INT);
$ordine = null; $righe = []; $storico = []; $statoSuccessivo = null; $messaggio = null; $ordine = null; // CARICATO
/* TODO SQL DI SUPPORTO - Caricare testata, righe con caratteristiche, $righe = []; // CARICATO
* ingredienti/procedura, indirizzo, stato corrente e storico dell'ordine. $caratteristiche = []; // CARICATO
* Input: $idOrdine. Output: attributi omonimi dello schema e nomi descrittivi. */ $storico = []; // CARICATO
$statoSuccessivo = null; // CARICATO
$messaggio = $_SESSION["messaggio"] ?? null;
unset($_SESSION["messaggio"]);
// Recupero l'ordine
$stmt = $pdo->prepare("
SELECT
uso.idOrdine,
uso.idStatoOrdine,
uso.nomeStato,
uso.posizione
FROM
ultimoStatoOrdini AS uso
WHERE
uso.idOrdine = :idOrdine
");
$stmt->execute([
"idOrdine" => $idOrdine
]);
$ordine = $stmt->fetch(PDO::FETCH_ASSOC) ?: null;
// Recupero delle righe
$stmt = $pdo->prepare("
SELECT
ro1.idRigaOrdine,
p1.nome AS nomeProdotto,
ro1.quantita,
p1.proceduraPreparazione
FROM
rigaOrdine AS ro1
JOIN prodotto AS p1
ON ro1.idProdotto = p1.idProdotto
WHERE
ro1.idOrdine = :idOrdine
");
$stmt->execute([
"idOrdine" => $idOrdine
]);
$righe = $stmt->fetchAll(PDO::FETCH_ASSOC);
// Recupero delle caratteristiche
$stmt = $pdo->prepare("
SELECT
ro1.idRigaOrdine,
GROUP_CONCAT(
CONCAT(c1.nome, ' - ', c1.descrizione)
SEPARATOR ', '
) AS caratteristiche
FROM
rigaOrdine AS ro1
JOIN rigaOrdineSelezionaCaratteristica AS rosc1
ON ro1.idRigaOrdine = rosc1.idRigaOrdine
JOIN caratteristica AS c1
ON rosc1.idCaratteristica = c1.idCaratteristica
WHERE
ro1.idOrdine = :idOrdine
GROUP BY
ro1.idRigaOrdine
");
$stmt->execute([
"idOrdine" => $idOrdine
]);
$caratteristiche = $stmt->fetchAll(PDO::FETCH_KEY_PAIR);
// Recupero lo storico
$stmt = $pdo->prepare("
SELECT
statoOrdini.timestamp,
statoOrdini.nomeStato,
statoOrdini.nomePersonale,
statoOrdini.cognomePersonale
FROM
statoOrdini
WHERE
statoOrdini.idOrdine = :idOrdine
");
$stmt->execute([
"idOrdine" => $idOrdine
]);
$storico = $stmt->fetchAll(PDO::FETCH_ASSOC);
// Recupero dello stato successivo
$stmt = $pdo->prepare("
SELECT
uso.idOrdine,
so1.idStatoOrdine,
so1.nomeStato,
so1.posizione
FROM
ultimoStatoOrdini AS uso
JOIN statoOrdine AS so1
ON so1.posizione = (
SELECT
MIN(so2.posizione)
FROM
statoOrdine AS so2
WHERE
so2.posizione > uso.posizione
)
WHERE
uso.idOrdine = :idOrdine
");
$stmt->execute([
"idOrdine" => $idOrdine
]);
$statoSuccessivo = $stmt->fetch(PDO::FETCH_ASSOC) ?: null;
if (postMethod()) { if (postMethod()) {
/*
* QUERY 14 - Aggiornamento progressivo dello stato di un ordine // Controllo input
* Input: $idOrdine, $idStatoOrdine, $idPersonale if (
* Output: nuovo nomeStato, posizione e timestamp registrato $idOrdine === null || $idOrdine === false ||
* Vincolo UI/DB: solo il successore dello stato corrente; mai regressioni. $idStatoOrdine === null || $idStatoOrdine === false ||
* TODO SQL: implementare manualmente la Query 14. $idPersonale <= 0
*/ ) {
$messaggio = "Query 14 predisposta: stato non ancora aggiornato."; $messaggio = "Errore: dati non validi per l'aggiornamento dello stato.";
} else {
// Aggiornamento dello stato attuale
try {
$pdo->beginTransaction();
// Ottengo il nuovo stato
$idStatoOrdineSuccessivo = $statoSuccessivo["idStatoOrdine"] ?? null;
$stmt = $pdo->prepare("
INSERT
INTO storicoStato
(
timestamp,
idOrdine,
idStatoOrdine,
idPersonale
)
VALUES (
NOW(),
:idOrdine,
:idStatoOrdine,
:idPersonale
)
");
$stmt->execute([
"idOrdine" => $idOrdine,
"idStatoOrdine" => $idStatoOrdineSuccessivo,
"idPersonale" => $idPersonale
]);
$pdo->commit();
// Pulizia
header("Location: dettaglio_ordine.php?idOrdine=" . $idOrdine);
// Messaggio
$_SESSION["messaggio"] = "Ordine aggiornato con successo";
exit;
} catch (PDOException $e) {
if ($pdo -> inTransaction()) {
$pdo -> rollback();
}
$messaggio =
"Errore durante l'aggiornamento dello stato dell'ordine" .
$e -> getMessage();
}
}
} }
$pageTitle = "Dettaglio ordine"; $basePath = ".."; $pageTitle = "Dettaglio ordine"; $basePath = "..";
require __DIR__ . "/../includes/header.php"; require __DIR__ . "/../includes/header.php";
?> ?>
<div class="d-flex justify-content-between"><h1 class="h3">Ordine #<?= e($idOrdine ?: "—") ?></h1><a class="btn btn-outline-secondary" href="ordini.php">Indietro</a></div>
<?php if (!$idOrdine): ?><div class="alert alert-danger">Specificare un ID ordine valido.</div><?php endif; ?> <div class="d-flex justify-content-between">
<?php if ($messaggio): ?><div class="alert alert-warning"><?= e($messaggio) ?></div><?php endif; ?> <h1 class="h3">Ordine #<?= e($idOrdine ?: "—") ?></h1>
<?php if (!$ordine): ?><div class="alert alert-info">Il dettaglio sarà disponibile dopo il TODO SQL di supporto.</div><?php endif; ?> <a class="btn btn-outline-secondary" href="ordini.php">Indietro</a>
</div>
<?php if (!$idOrdine): ?>
<div class="alert alert-danger">Specificare un ID ordine valido.</div>
<?php endif; ?>
<?php if ($messaggio): ?>
<div class="alert alert-warning"><?= e($messaggio) ?></div>
<?php endif; ?>
<?php if (!$ordine): ?>
<div class="alert alert-info">Il dettaglio sarà disponibile dopo il TODO SQL di supporto.</div>
<?php endif; ?>
<div class="row g-4"><div class="col-lg-8"> <div class="row g-4"><div class="col-lg-8">
<div class="card shadow-sm mb-3"><div class="card-body"><h2 class="h5">Preparazione</h2><table class="table"><thead><tr><th>Prodotto</th><th>Qtà</th><th>Caratteristiche</th><th>Procedura</th></tr></thead><tbody><?php foreach ($righe as $r): ?><tr><td><?= e($r["nomeProdotto"]) ?></td><td><?= e($r["quantita"]) ?></td><td><?= e($r["caratteristiche"] ?? "—") ?></td><td><?= e($r["proceduraPreparazione"] ?? "—") ?></td></tr><?php endforeach; ?></tbody></table></div></div> <div class="card shadow-sm mb-3">
<div class="card shadow-sm"><div class="card-body"><h2 class="h5">Storico stati</h2><ol class="mb-0"><?php foreach ($storico as $s): ?><li><?= e($s["timestamp"]) ?> — <?= e($s["nomeStato"]) ?> (<?= e(($s["nomePersonale"] ?? "") . " " . ($s["cognomePersonale"] ?? "")) ?>)</li><?php endforeach; ?></ol></div></div> <div class="card-body">
</div><div class="col-lg-4"><div class="card shadow-sm"><div class="card-body"><h2 class="h5">Avanzamento</h2><p>Corrente: <span class="badge bg-primary"><?= e($ordine["nomeStato"] ?? "—") ?></span></p><p class="small text-muted">Progressione: inserito → in preparazione → pronto → in consegna → consegnato.</p><form method="post"><input type="hidden" name="idOrdine" value="<?= e($idOrdine) ?>"><input type="hidden" name="idStatoOrdine" value="<?= e($statoSuccessivo["idStatoOrdine"] ?? "") ?>"><button class="btn btn-success w-100" <?= $statoSuccessivo ? "" : "disabled" ?>>Passa a: <?= e($statoSuccessivo["nomeStato"] ?? "nessuno") ?></button></form></div></div></div></div> <h2 class="h5">Preparazione</h2>
<table class="table">
<thead>
<tr>
<th>Prodotto</th>
<th>Qtà</th>
<th>Caratteristiche</th>
<th>Procedura</th>
</tr>
</thead>
<tbody>
<?php foreach ($righe as $r): ?>
<tr>
<td>
<?= e($r["nomeProdotto"]) ?>
</td>
<td>
<?= e($r["quantita"]) ?>
</td>
<td>
<?= e($caratteristiche[$r["idRigaOrdine"]] ?? "—") ?>
</td>
<td>
<?= e($r["proceduraPreparazione"] ?? "—") ?>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
</div>
<div class="card shadow-sm">
<div class="card-body">
<h2 class="h5">Storico stati</h2>
<ol class="mb-0">
<?php foreach ($storico as $s): ?>
<li><?= e($s["timestamp"]) ?> — <?= e($s["nomeStato"]) ?> (<?= e(($s["nomePersonale"] ?? "") . " " . ($s["cognomePersonale"] ?? "")) ?>)</li>
<?php endforeach; ?>
</ol>
</div>
</div>
</div>
<div class="col-lg-4">
<div class="card shadow-sm">
<div class="card-body">
<h2 class="h5">Avanzamento</h2>
<p>Corrente: <span class="badge bg-primary"><?= e($ordine["nomeStato"] ?? "—") ?></span></p>
<p class="small text-muted">Progressione: inserito → in preparazione → pronto → in consegna → consegnato.</p>
<form method="post">
<input type="hidden" name="idOrdine" value="<?= e($idOrdine) ?>">
<input type="hidden" name="idStatoOrdine" value="<?= e($statoSuccessivo["idStatoOrdine"] ?? "") ?>">
<button class="btn btn-success w-100" <?= $statoSuccessivo ? "" : "disabled" ?>>Passa a: <?= e($statoSuccessivo["nomeStato"] ?? "nessuno") ?></button>
</form>
</div>
</div>
</div>
</div>
<?php require __DIR__ . "/../includes/footer.php"; ?> <?php require __DIR__ . "/../includes/footer.php"; ?>
+600 -15
View File
@@ -1,24 +1,609 @@
<?php <?php
require_once __DIR__ . "/../includes/auth.php"; require_once __DIR__ . "/../includes/auth.php";
requireRole("personale"); requireRole("personale");
require_once __DIR__ . "/../config/database.php"; require_once __DIR__ . "/../config/database.php";
$idPersonale = (int) $_SESSION["idUtente"]; $idPersonale = (int) $_SESSION["idUtente"];
$soloInRitardo = ($_GET["filtro"] ?? "") === "ritardo"; $soloInRitardo = ($_GET["filtro"] ?? "") === "ritardo";
$ordini = []; $ordini = [];
/*
* QUERY 5 - Ordini non ancora messi in preparazione dopo più di un'ora $stmt = $pdo->prepare("
* Input: nessuno; $soloInRitardo controlla la vista richiesta dalla UI SELECT
* Output atteso: idOrdine, dataOraCreazione, orarioConsegna, totale, o1.idOrdine,
* nomeCliente, cognomeCliente, via, numeroCivico, nomeComune, o1.dataOraCreazione,
* nomeStato, timestampUltimoStato, minutiAttesa o1.orarioConsegna,
* TODO SQL: implementare manualmente la Query 5. o1.totale,
*/ o1.idCliente,
/* Per la vista completa degli ordini correnti predisporre inoltre una query o1.idIndirizzo,
* di supporto con gli stessi campi, senza il vincolo "oltre un'ora". */ abitazione.via,
$pageTitle = "Ordini correnti"; $basePath = ".."; abitazione.numeroCivico,
abitazione.nomeComune,
clienti.nome AS nomeCliente,
clienti.cognome AS cognomeCliente,
stati.nomeStato,
stati.timestampUltimoStato,
TIMESTAMPDIFF(
MINUTE,
stati.timestampUltimoStato,
CURRENT_TIMESTAMP
) AS minutiAttesa
FROM
ordine AS o1
LEFT JOIN (
SELECT
ss2.idOrdine,
so2.nomeStato,
ss2.timestamp AS timestampUltimoStato
FROM
storicoStato AS ss2
JOIN statoOrdine AS so2
ON ss2.idStatoOrdine = so2.idStatoOrdine
WHERE
so2.posizione = (
SELECT
MAX(so3.posizione)
FROM
storicoStato AS ss3
JOIN statoOrdine AS so3
ON ss3.idStatoOrdine = so3.idStatoOrdine
WHERE
ss3.idOrdine = ss2.idOrdine
)
) AS stati
ON o1.idOrdine = stati.idOrdine
LEFT JOIN (
SELECT
c4.idUtente,
u4.nome,
u4.cognome
FROM
cliente AS c4
JOIN utente AS u4
ON u4.idUtente = c4.idUtente
) AS clienti
ON o1.idCliente = clienti.idUtente
LEFT JOIN (
SELECT
i5.idIndirizzo,
i5.via,
i5.numeroCivico,
c5.nome AS nomeComune
FROM
indirizzo AS i5
JOIN comune AS c5
ON i5.idComune = c5.idComune
) AS abitazione
ON o1.idIndirizzo = abitazione.idIndirizzo
WHERE
1
");
$stmt->execute();
$ordini = $stmt->fetchAll(PDO::FETCH_ASSOC);
// Dati di riepilogo ottenuti dagli ordini già caricati
$numeroOrdini = count($ordini);
$numeroInRitardo = count(
array_filter(
$ordini,
function ($ordine) {
return isset($ordine["minutiAttesa"])
&& (int) $ordine["minutiAttesa"] >= 60;
}
)
);
$valoreTotaleOrdini = array_sum(
array_map(
function ($ordine) {
return (float) ($ordine["totale"] ?? 0);
},
$ordini
)
);
$pageTitle = "Ordini correnti";
$basePath = "..";
require __DIR__ . "/../includes/header.php"; require __DIR__ . "/../includes/header.php";
?>
<div class="d-flex justify-content-between align-items-center mb-4">
<div>
<h1 class="h3 mb-1">
Ordini correnti
</h1>
<div class="text-muted">
Gestione degli ordini attualmente presenti nel sistema
</div>
</div>
<div>
<a
class="btn btn-outline-secondary"
href="ordini.php"
>
Tutti
</a>
<a
class="btn btn-warning"
href="?filtro=ritardo"
>
In attesa da oltre un'ora (Q5)
</a>
</div>
</div>
<!-- RIEPILOGO -->
<div class="row g-3 mb-4">
<div class="col-md-4">
<div class="card shadow-sm h-100">
<div class="card-body">
<div class="text-muted small">
Ordini visualizzati
</div>
<div class="fs-3 fw-bold">
<?= e($numeroOrdini) ?>
</div>
</div>
</div>
</div>
<div class="col-md-4">
<div class="card shadow-sm h-100">
<div class="card-body">
<div class="text-muted small">
In attesa da almeno 60 minuti
</div>
<div class="fs-3 fw-bold text-danger">
<?= e($numeroInRitardo) ?>
</div>
</div>
</div>
</div>
<div class="col-md-4">
<div class="card shadow-sm h-100">
<div class="card-body">
<div class="text-muted small">
Valore complessivo
</div>
<div class="fs-3 fw-bold">
<?= number_format(
$valoreTotaleOrdini,
2,
",",
"."
) ?> €
</div>
</div>
</div>
</div>
</div>
<?php if (!$ordini): ?>
<div class="alert alert-info">
Nessun risultato: completare la Query 5 o il caricamento di supporto.
</div>
<?php else: ?>
<div class="card shadow-sm">
<div class="card-header">
<strong>
Elenco ordini
</strong>
</div>
<div class="table-responsive">
<table class="table table-hover align-middle mb-0">
<thead class="table-light">
<tr>
<th>
Ordine
</th>
<th>
Cliente
</th>
<th>
Indirizzo
</th>
<th>
Creato
</th>
<th>
Stato
</th>
<th>
Ultimo aggiornamento
</th>
<th>
Attesa
</th>
<th>
Consegna
</th>
<th class="text-end">
Totale
</th>
<th>
</th>
</tr>
</thead>
<tbody>
<?php foreach ($ordini as $o): ?>
<?php
$minutiAttesa = null;
if (isset($o["minutiAttesa"])) {
$minutiAttesa = (int) $o["minutiAttesa"];
}
// Colore badge attesa
if ($minutiAttesa === null) {
$classeAttesa = "bg-secondary";
} elseif ($minutiAttesa >= 60) {
$classeAttesa = "bg-danger";
} elseif ($minutiAttesa >= 30) {
$classeAttesa = "bg-warning text-dark";
} else {
$classeAttesa = "bg-success";
}
// Colore badge stato
switch ($o["nomeStato"] ?? "") {
case "inserito":
$classeStato = "bg-secondary";
break;
case "in preparazione":
$classeStato = "bg-warning text-dark";
break;
case "pronto":
$classeStato = "bg-info text-dark";
break;
case "in consegna":
$classeStato = "bg-primary";
break;
case "consegnato":
$classeStato = "bg-success";
break;
default:
$classeStato = "bg-secondary";
break;
}
?>
<tr>
<!-- ID ORDINE -->
<td>
<strong>
#<?= e($o["idOrdine"]) ?>
</strong>
</td>
<!-- CLIENTE -->
<td>
<div class="fw-semibold">
<?= e(
($o["nomeCliente"] ?? "")
. " "
. ($o["cognomeCliente"] ?? "")
) ?>
</div>
<div class="small text-muted">
Cliente #<?= e($o["idCliente"]) ?>
</div>
</td>
<!-- INDIRIZZO -->
<td>
<div>
<?= e(
($o["via"] ?? "")
. " "
. ($o["numeroCivico"] ?? "")
) ?>
</div>
<div class="small text-muted">
<?= e(
$o["nomeComune"] ?? ""
) ?>
</div>
</td>
<!-- DATA CREAZIONE -->
<td>
<?php if (!empty($o["dataOraCreazione"])): ?>
<?= e(
date(
"d/m/Y H:i",
strtotime(
$o["dataOraCreazione"]
)
)
) ?>
<?php else: ?>
<span class="text-muted">
</span>
<?php endif; ?>
</td>
<!-- STATO -->
<td>
<span class="badge <?= $classeStato ?>">
<?= e(
$o["nomeStato"] ?? "Sconosciuto"
) ?>
</span>
</td>
<!-- TIMESTAMP ULTIMO STATO -->
<td>
<?php if (!empty($o["timestampUltimoStato"])): ?>
<?= e(
date(
"d/m/Y H:i",
strtotime(
$o["timestampUltimoStato"]
)
)
) ?>
<?php else: ?>
<span class="text-muted">
</span>
<?php endif; ?>
</td>
<!-- MINUTI ATTESA -->
<td>
<?php if ($minutiAttesa !== null): ?>
<span class="badge <?= $classeAttesa ?>">
<?= e($minutiAttesa) ?> min
</span>
<?php else: ?>
<span class="text-muted">
</span>
<?php endif; ?>
</td>
<!-- ORARIO CONSEGNA -->
<td>
<?php if (!empty($o["orarioConsegna"])): ?>
<?= e(
date(
"d/m/Y H:i",
strtotime(
$o["orarioConsegna"]
)
)
) ?>
<?php else: ?>
<span class="text-muted">
Non definita
</span>
<?php endif; ?>
</td>
<!-- TOTALE -->
<td class="text-end fw-semibold">
<?= number_format(
(float) ($o["totale"] ?? 0),
2,
",",
"."
) ?> €
</td>
<!-- DETTAGLIO -->
<td class="text-end">
<a
class="btn btn-sm btn-primary"
href="dettaglio_ordine.php?idOrdine=<?= e($o["idOrdine"]) ?>"
>
Dettaglio
</a>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
</div>
<?php endif; ?>
<?php
require __DIR__ . "/../includes/footer.php";
?> ?>
<div class="d-flex justify-content-between align-items-center mb-3"><h1 class="h3">Ordini correnti</h1><div><a class="btn btn-outline-secondary" href="ordini.php">Tutti</a> <a class="btn btn-warning" href="?filtro=ritardo">In attesa da oltre un'ora (Q5)</a></div></div>
<?php if (!$ordini): ?><div class="alert alert-info">Nessun risultato: completare la Query 5 o il caricamento di supporto.</div><?php endif; ?>
<div class="table-responsive"><table class="table table-striped align-middle"><thead><tr><th>Ordine</th><th>Cliente</th><th>Creato</th><th>Stato</th><th>Attesa</th><th>Consegna</th><th></th></tr></thead><tbody><?php foreach ($ordini as $o): ?><tr><td>#<?= e($o["idOrdine"]) ?></td><td><?= e(($o["nomeCliente"] ?? "") . " " . ($o["cognomeCliente"] ?? "")) ?></td><td><?= e($o["dataOraCreazione"]) ?></td><td><span class="badge bg-secondary"><?= e($o["nomeStato"]) ?></span></td><td><?= e($o["minutiAttesa"] ?? "—") ?> min</td><td><?= e($o["orarioConsegna"]) ?></td><td><a class="btn btn-sm btn-primary" href="dettaglio_ordine.php?idOrdine=<?= e($o["idOrdine"]) ?>">Dettaglio</a></td></tr><?php endforeach; ?></tbody></table></div>
<?php require __DIR__ . "/../includes/footer.php"; ?>
+163 -5
View File
@@ -1,6 +1,41 @@
<?php <?php
require_once __DIR__."/../includes/auth.php";requireRole("proprietario");require_once __DIR__."/../config/database.php"; require_once __DIR__."/../includes/auth.php";requireRole("proprietario");require_once __DIR__."/../config/database.php";
$idOrdine=filter_input(INPUT_GET,"idOrdine",FILTER_VALIDATE_INT);$stato=trim($_GET["stato"]??"");$ordini=[];$personaleOrdine=[]; $idOrdine=filter_input(INPUT_GET,"idOrdine",FILTER_VALIDATE_INT);
$stato=trim($_GET["stato"]??"");
$ordini=[];
$personaleOrdine=[];
// Ricavo gli ordini
$stmt = $pdo->prepare("
SELECT
o1.idOrdine,
CONCAT(u1.nome, ' ', u1.cognome) AS cliente,
o1.dataOraCreazione,
o1.statoConferma,
uso1.nomeStato,
o1.orarioConsegna,
o1.totale
FROM
ordine AS o1
LEFT JOIN ultimoStatoOrdini AS uso1
ON o1.idOrdine = uso1.idOrdine
LEFT JOIN cliente AS c1
ON o1.idCliente = c1.idUtente
LEFT JOIN utente AS u1
ON c1.idUtente = u1.idUtente
WHERE
1
");
$stmt->execute();
$ordini = $stmt->fetchAll(PDO::FETCH_ASSOC);
/* TODO SQL DI SUPPORTO - Monitorare ordini passati, attivi ed evasi. /* TODO SQL DI SUPPORTO - Monitorare ordini passati, attivi ed evasi.
* Input: $stato. Output: idOrdine, cliente, dataOraCreazione, statoConferma, * Input: $stato. Output: idOrdine, cliente, dataOraCreazione, statoConferma,
* nomeStato, orarioConsegna, totale, indirizzo. */ * nomeStato, orarioConsegna, totale, indirizzo. */
@@ -11,10 +46,133 @@ if($idOrdine){
* Output atteso: idUtente, nome, cognome, email, numeroCambiStato, * Output atteso: idUtente, nome, cognome, email, numeroCambiStato,
* primoIntervento, ultimoIntervento * primoIntervento, ultimoIntervento
* TODO SQL: implementare manualmente la Query 13. * TODO SQL: implementare manualmente la Query 13.
*/} */
// Membri del personale che hanno lavorato a un ordine
$stmt = $pdo->prepare("
SELECT
u1.idUtente,
u1.nome,
u1.cognome,
u1.email,
COUNT(ss1.idStoricoStato) AS numeroCambiStato,
MIN(ss1.timestamp) AS primoIntervento,
MAX(ss1.timestamp) AS ultimoIntervento
FROM
storicoStato AS ss1
JOIN personale AS p1
ON ss1.idPersonale = p1.idUtente
JOIN utente AS u1
ON p1.idUtente = u1.idUtente
WHERE
ss1.idOrdine = :idOrdine
GROUP BY
u1.idUtente,
u1.nome,
u1.cognome,
u1.email
ORDER BY
primoIntervento
");
$stmt->execute([
"idOrdine" => $idOrdine
]);
$personaleOrdine = $stmt->fetchAll(PDO::FETCH_ASSOC);
}
$pageTitle="Monitoraggio ordini";$basePath="..";require __DIR__."/../includes/header.php"; $pageTitle="Monitoraggio ordini";$basePath="..";require __DIR__."/../includes/header.php";
?> ?>
<h1 class="h3">Monitoraggio ordini</h1><form method="get" class="card card-body mb-3"><div class="row g-3 align-items-end"><div class="col-md-4"><label class="form-label">Stato</label><select class="form-select" name="stato"><option value="">Tutti</option><?php foreach(["inserito","in preparazione","pronto","in consegna","consegnato"] as $s):?><option <?=$stato===$s?"selected":""?>><?=e($s)?></option><?php endforeach;?></select></div><div class="col-md-4"><label class="form-label">ID ordine per personale (Q13)</label><input class="form-control" type="number" min="1" name="idOrdine" value="<?=e($idOrdine)?>"></div><div class="col-md-2"><button class="btn btn-primary">Applica</button></div></div></form> <h1 class="h3">Monitoraggio ordini</h1>
<?php if(!$ordini):?><div class="alert alert-info">Completare il TODO SQL per visualizzare gli ordini.</div><?php endif;?><div class="table-responsive"><table class="table table-striped"><thead><tr><th>ID</th><th>Cliente</th><th>Creazione</th><th>Conferma</th><th>Stato</th><th>Consegna</th><th>Totale</th></tr></thead><tbody><?php foreach($ordini as $o):?><tr><td><?=e($o["idOrdine"])?></td><td><?=e($o["cliente"])?></td><td><?=e($o["dataOraCreazione"])?></td><td><?=e($o["statoConferma"])?></td><td><?=e($o["nomeStato"]??"—")?></td><td><?=e($o["orarioConsegna"])?></td><td>€ <?=e($o["totale"])?></td></tr><?php endforeach;?></tbody></table></div> <form method="get" class="card card-body mb-3">
<?php if($idOrdine):?><div class="card card-body mt-4"><h2 class="h5">Personale dell'ordine #<?=e($idOrdine)?> (Q13)</h2><?php if(!$personaleOrdine):?><p class="text-muted">Risultati disponibili dopo la Query 13.</p><?php endif;?><table class="table"><thead><tr><th>Nome</th><th>Email</th><th>Cambi stato</th><th>Primo</th><th>Ultimo</th></tr></thead><tbody><?php foreach($personaleOrdine as $p):?><tr><td><?=e($p["nome"]." ".$p["cognome"])?></td><td><?=e($p["email"])?></td><td><?=e($p["numeroCambiStato"])?></td><td><?=e($p["primoIntervento"])?></td><td><?=e($p["ultimoIntervento"])?></td></tr><?php endforeach;?></tbody></table></div><?php endif;?> <div class="row g-3 align-items-end">
<div class="col-md-4">
<label class="form-label">Stato</label>
<select class="form-select" name="stato">
<option value="">Tutti</option>
<?php foreach(["inserito","in preparazione","pronto","in consegna","consegnato"] as $s):?>
<option <?=$stato===$s?"selected":""?>><?=e($s)?></option>
<?php endforeach;?>
</select>
</div>
<div class="col-md-4">
<label class="form-label">ID ordine per personale (Q13)</label>
<input class="form-control" type="number" min="1" name="idOrdine" value="<?=e($idOrdine)?>">
</div>
<div class="col-md-2">
<button class="btn btn-primary">Applica</button>
</div>
</div>
</form>
<?php if(!$ordini):?>
<div class="alert alert-info">Completare il TODO SQL per visualizzare gli ordini.</div>
<?php endif;?>
<div class="table-responsive">
<table class="table table-striped">
<thead>
<tr>
<th>ID</th>
<th>Cliente</th>
<th>Creazione</th>
<th>Conferma</th>
<th>Stato</th>
<th>Consegna</th>
<th>Totale</th>
</tr>
</thead>
<tbody>
<?php foreach($ordini as $o):?>
<tr>
<td><?=e($o["idOrdine"])?></td>
<td><?=e($o["cliente"])?></td>
<td><?=e($o["dataOraCreazione"])?></td>
<td><?=e($o["statoConferma"])?></td>
<td><?=e($o["nomeStato"]??"—")?></td>
<td><?=e($o["orarioConsegna"])?></td>
<td>€ <?=e($o["totale"])?></td>
</tr>
<?php endforeach;?>
</tbody>
</table>
</div>
<?php if($idOrdine):?>
<div class="card card-body mt-4">
<h2 class="h5">Personale dell'ordine #<?=e($idOrdine)?> (Q13)</h2>
<?php if(!$personaleOrdine):?>
<p class="text-muted">Risultati disponibili dopo la Query 13.</p>
<?php endif;?>
<table class="table">
<thead>
<tr>
<th>Nome</th>
<th>Email</th>
<th>Cambi stato</th>
<th>Primo</th>
<th>Ultimo</th>
</tr></thead>
<tbody>
<?php foreach($personaleOrdine as $p):?>
<tr>
<td><?=e($p["nome"]." ".$p["cognome"])?></td>
<td><?=e($p["email"])?></td>
<td><?=e($p["numeroCambiStato"])?></td>
<td><?=e($p["primoIntervento"])?></td>
<td><?=e($p["ultimoIntervento"])?></td>
</tr>
<?php endforeach;?>
</tbody>
</table>
</div>
<?php endif;?>
<?php require __DIR__."/../includes/footer.php";?> <?php require __DIR__."/../includes/footer.php";?>
+66 -1
View File
@@ -88,7 +88,13 @@ CREATE TABLE ordine (
-- CREAZIONE RELAZIONE STATO ORDINE -- CREAZIONE RELAZIONE STATO ORDINE
CREATE TABLE statoOrdine ( CREATE TABLE statoOrdine (
idStatoOrdine INT PRIMARY KEY AUTO_INCREMENT NOT NULL, idStatoOrdine INT PRIMARY KEY AUTO_INCREMENT NOT NULL,
nomeStato VARCHAR(30) NOT NULL, nomeStato ENUM(
'inserito',
'in preparazione',
'pronto',
'in consegna',
'consegnato'
),
posizione TINYINT NOT NULL posizione TINYINT NOT NULL
); );
@@ -192,3 +198,62 @@ CREATE TABLE rigaOrdineSelezionaCaratteristica (
FOREIGN KEY (idCaratteristica) REFERENCES caratteristica (idCaratteristica), FOREIGN KEY (idCaratteristica) REFERENCES caratteristica (idCaratteristica),
FOREIGN KEY (idRigaOrdine) REFERENCES rigaOrdine (idRigaOrdine) FOREIGN KEY (idRigaOrdine) REFERENCES rigaOrdine (idRigaOrdine)
); );
-- CREAZIONE VISTE (RECUPERO ULTIMO STATO ORDINE)
CREATE VIEW ultimoStatoOrdini AS (
SELECT
ss1.idOrdine,
ss1.idStatoOrdine,
so1.nomeStato,
so1.posizione
FROM
storicoStato AS ss1
JOIN statoOrdine AS so1
ON ss1.idStatoOrdine = so1.idStatoOrdine
WHERE
so1.posizione = (
SELECT
MAX(so2.posizione)
FROM
storicoStato AS ss2
JOIN statoOrdine AS so2
ON ss2.idStatoOrdine = so2.idStatoOrdine
WHERE
ss2.idOrdine = ss1.idOrdine
)
);
-- CREAZIONE VISTE (RECUPERO STATO COMPLETO ORDINE)
CREATE VIEW statoOrdini AS (
SELECT
ss1.idOrdine,
ss1.idStatoOrdine,
ss1.idPersonale,
u1.nome AS nomePersonale,
u1.cognome AS cognomePersonale,
ss1.timestamp,
so1.nomeStato
FROM storicoStato AS ss1
JOIN statoOrdine AS so1
ON ss1.idStatoOrdine = so1.idStatoOrdine
LEFT JOIN personale AS p1
ON ss1.idPersonale = p1.idUtente
LEFT JOIN utente AS u1
ON p1.idUtente = u1.idUtente
WHERE
1
ORDER BY
ss1.timestamp
);
+2
View File
@@ -1,2 +1,4 @@
[+] Preferiti: Il cliente può avere dei prodotti preferiti [+] Preferiti: Il cliente può avere dei prodotti preferiti
[+] Immagini [+] Immagini
[+] OKOKFATTO,CARICATO keywords da eliminare