diff --git a/public/userarea/get_matrice_lines.php b/public/userarea/get_matrice_lines.php new file mode 100644 index 0000000..9ec3118 --- /dev/null +++ b/public/userarea/get_matrice_lines.php @@ -0,0 +1,36 @@ + false, 'message' => 'Invalid id']); + exit; + } + + $db = DBHandlerSelect::getInstance(); + $pdo = $db->getConnection(); + + // tutte le linee (attive + inattive se vuoi: qui prendo tutte) + $stmt = $pdo->query(" + SELECT id, line_number, name + FROM production_lines + ORDER BY line_number ASC + "); + $lines = $stmt->fetchAll(PDO::FETCH_ASSOC); + + // linee già associate + $stmt = $pdo->prepare("SELECT idlinea FROM matrici_lines WHERE idmatrice = ?"); + $stmt->execute([$idmatrice]); + $selected_ids = $stmt->fetchAll(PDO::FETCH_COLUMN); + + echo json_encode([ + 'success' => true, + 'lines' => $lines, + 'selected_ids' => $selected_ids + ]); +} catch (Throwable $e) { + echo json_encode(['success' => false, 'message' => 'Server error']); +} diff --git a/public/userarea/get_matrice_mescole.php b/public/userarea/get_matrice_mescole.php new file mode 100644 index 0000000..97f512a --- /dev/null +++ b/public/userarea/get_matrice_mescole.php @@ -0,0 +1,35 @@ + false, 'message' => 'Invalid id']); + exit; + } + + $db = DBHandlerSelect::getInstance(); + $pdo = $db->getConnection(); + + // tutte le mescole + $stmt = $pdo->query(" + SELECT id, nome, nomeuscita + FROM mescole + ORDER BY nome ASC + "); + $mescole = $stmt->fetchAll(PDO::FETCH_ASSOC); + + // mescole già associate + $stmt = $pdo->prepare("SELECT idmescola FROM matrici_mescole WHERE idmatrice = ?"); + $stmt->execute([$idmatrice]); + $selected_ids = $stmt->fetchAll(PDO::FETCH_COLUMN); + + echo json_encode([ + 'success' => true, + 'mescole' => $mescole, + 'selected_ids' => $selected_ids + ]); +} catch (Throwable $e) { + echo json_encode(['success' => false, 'message' => 'Server error']); +} diff --git a/public/userarea/matrici.php b/public/userarea/matrici.php index f8fb4cc..088c328 100644 --- a/public/userarea/matrici.php +++ b/public/userarea/matrici.php @@ -11,13 +11,12 @@ - - + @@ -176,13 +175,14 @@ max-width: 320px; } - /* Data: piccola */ + /* Linee: media */ #tabellaMatrici th:nth-child(4), #tabellaMatrici td:nth-child(4) { - width: 120px; - max-width: 120px; + width: 220px; + max-width: 220px; } + /* Azioni: fissa */ #tabellaMatrici th:nth-child(5), #tabellaMatrici td:nth-child(5) { @@ -230,7 +230,7 @@ Foto Nome Cliente - Data + Linee Azioni @@ -241,7 +241,34 @@ $db = DBHandlerSelect::getInstance(); $pdo = $db->getConnection(); - $stmt = $pdo->query("SELECT * FROM matrice ORDER BY id DESC"); + $stmt = $pdo->query(" + SELECT + m.*, + COALESCE(lg.linee_associate, '—') AS linee_associate, + COALESCE(mg.mescole_associate, '') AS mescole_associate, + COALESCE(mg.mescole_count, 0) AS mescole_count + FROM matrice m + LEFT JOIN ( + SELECT + ml.idmatrice, + GROUP_CONCAT(pl.name ORDER BY pl.name SEPARATOR ', ') AS linee_associate + FROM matrici_lines ml + JOIN production_lines pl ON pl.id = ml.idlinea + GROUP BY ml.idmatrice + ) lg ON lg.idmatrice = m.id + LEFT JOIN ( + SELECT + mm.idmatrice, + GROUP_CONCAT(ms.nome ORDER BY ms.nome SEPARATOR ', ') AS mescole_associate, + COUNT(*) AS mescole_count + FROM matrici_mescole mm + JOIN mescole ms ON ms.id = mm.idmescola + GROUP BY mm.idmatrice + ) mg ON mg.idmatrice = m.id + ORDER BY m.id DESC + "); + + function formatDateIT($d) { @@ -300,31 +327,61 @@ . ""; - // colonna DATA - echo "{$dataIT}"; + // colonna LINEE + $lineeTxt = $row['linee_associate'] ?? '—'; + $mescoleTxt = $row['mescole_associate'] ?? ''; + $mescoleCount = (int)($row['mescole_count'] ?? 0); + + $btnMescole = ''; + if ($mescoleCount > 0) { + $btnMescole = " "; + } + + echo "" + . htmlspecialchars($lineeTxt) + . $btnMescole + . ""; + // colonna AZIONI echo " - + - + - + + + + + "; - - "; echo ""; } @@ -382,6 +439,70 @@ + + + + + + @@ -483,6 +604,180 @@ } }); }); + // Bootstrap 5 tooltips + document.querySelectorAll('[data-bs-toggle="tooltip"]').forEach(el => new bootstrap.Tooltip(el)); + + // === LINEE ASSOCIATE (MODALE) === + + // init Select2 (dentro modal) + $('#ml_linee').select2({ + theme: 'bootstrap-5', + dropdownParent: $('#matriceLineeModal'), + placeholder: 'Seleziona le linee...' + }); + + // open modal + load data + $(document).on("click", ".linee", function() { + const idmatrice = $(this).data("id"); + const nome = $(this).data("nome") || ""; + + $("#ml_idmatrice").val(idmatrice); + $("#ml_matrice_name").text(nome); + + // pulizia select + const $sel = $("#ml_linee"); + $sel.empty().trigger("change"); + + fetch("get_matrice_lines.php?id=" + encodeURIComponent(idmatrice)) + .then(r => r.json()) + .then(data => { + if (!data.success) { + Swal.fire({ + icon: "error", + title: "Errore", + text: data.message || "Impossibile caricare le linee" + }); + return; + } + + // riempi opzioni linee + data.lines.forEach(l => { + const label = `Linea ${l.line_number} - ${l.name}`; + const opt = new Option(label, l.id, false, false); + $sel.append(opt); + }); + + // seleziona quelle già associate + $sel.val((data.selected_ids || []).map(String)).trigger("change"); + + // apri modale (BS5) + const modal = new bootstrap.Modal(document.getElementById('matriceLineeModal')); + modal.show(); + }); + }); + + // save associations + $("#ml_save_btn").on("click", function() { + const idmatrice = $("#ml_idmatrice").val(); + const selected = $("#ml_linee").val() || []; // array di idlinea + + fetch("save_matrice_lines.php", { + method: "POST", + headers: { + "Content-Type": "application/x-www-form-urlencoded" + }, + body: "idmatrice=" + encodeURIComponent(idmatrice) + + "&idlinee=" + encodeURIComponent(JSON.stringify(selected)) + }) + .then(r => r.json()) + .then(data => { + Swal.fire({ + icon: data.success ? "success" : "error", + title: data.success ? "Salvato!" : "Errore", + text: data.message || "" + }).then(() => { + if (data.success) { + bootstrap.Modal.getInstance(document.getElementById('matriceLineeModal')).hide(); + } + }); + }); + }); + // === MESCOLE ASSOCIATE (MODALE) === + + // init Select2 (dentro modal) + $('#mm_mescole').select2({ + theme: 'bootstrap-5', + dropdownParent: $('#matriceMescoleModal'), + placeholder: 'Cerca e seleziona le mescole...', + minimumResultsForSearch: 0, // <-- search sempre visibile + width: '100%' + }); + + + // open modal + load data + $(document).on("click", ".mescole", function() { + const idmatrice = $(this).data("id"); + const nome = $(this).data("nome") || ""; + + $("#mm_idmatrice").val(idmatrice); + $("#mm_matrice_name").text(nome); + + const $sel = $("#mm_mescole"); + $sel.empty().trigger("change"); + + fetch("get_matrice_mescole.php?id=" + encodeURIComponent(idmatrice)) + .then(r => r.json()) + .then(data => { + if (!data.success) { + Swal.fire({ + icon: "error", + title: "Errore", + text: data.message || "Impossibile caricare le mescole" + }); + return; + } + + // riempi opzioni mescole + data.mescole.forEach(m => { + const label = m.nomeuscita ? `${m.nome} (${m.nomeuscita})` : m.nome; + const opt = new Option(label, m.id, false, false); + $sel.append(opt); + }); + + // seleziona quelle già associate + $sel.val((data.selected_ids || []).map(String)).trigger("change"); + + // apri modale (BS5) + const modal = new bootstrap.Modal(document.getElementById('matriceMescoleModal')); + modal.show(); + }); + }); + + // save associations + $("#mm_save_btn").on("click", function() { + const idmatrice = $("#mm_idmatrice").val(); + const selected = $("#mm_mescole").val() || []; // array di idmescola + + fetch("save_matrice_mescole.php", { + method: "POST", + headers: { + "Content-Type": "application/x-www-form-urlencoded" + }, + body: "idmatrice=" + encodeURIComponent(idmatrice) + + "&idmescole=" + encodeURIComponent(JSON.stringify(selected)) + }) + .then(r => r.json()) + .then(data => { + Swal.fire({ + icon: data.success ? "success" : "error", + title: data.success ? "Salvato!" : "Errore", + text: data.message || "" + }).then(() => { + if (data.success) { + bootstrap.Modal.getInstance(document.getElementById('matriceMescoleModal')).hide(); + } + }); + }); + }); + + // click: mostra elenco mescole associate (read-only) + $(document).on('click', '.show-mescole', function() { + const nome = $(this).data('nome') || ''; + const mescole = $(this).data('mescole') || ''; + + $("#mlm_matrice_name").text(nome); + + if (!mescole.trim()) { + $("#mlm_list").html("Nessuna mescola associata"); + } else { + // elenco in badge + const items = mescole.split(',').map(s => s.trim()).filter(Boolean); + $("#mlm_list").html(items.map(x => `${x}`).join('')); + } + + const modal = new bootstrap.Modal(document.getElementById('mescoleListModal')); + modal.show(); + }); }); @@ -523,6 +818,24 @@ + + diff --git a/public/userarea/save_matrice_lines.php b/public/userarea/save_matrice_lines.php new file mode 100644 index 0000000..1a89060 --- /dev/null +++ b/public/userarea/save_matrice_lines.php @@ -0,0 +1,43 @@ + false, 'message' => 'Invalid idmatrice']); + exit; + } + if (!is_array($idlinee)) $idlinee = []; + + // normalizza a int e rimuovi duplicati + $idlinee = array_values(array_unique(array_filter(array_map('intval', $idlinee), fn($v) => $v > 0))); + + $db = DBHandlerSelect::getInstance(); + $pdo = $db->getConnection(); + + $pdo->beginTransaction(); + + // rimuovi vecchie associazioni + $stmt = $pdo->prepare("DELETE FROM matrici_lines WHERE idmatrice = ?"); + $stmt->execute([$idmatrice]); + + // inserisci nuove + if (!empty($idlinee)) { + $stmt = $pdo->prepare("INSERT INTO matrici_lines (idmatrice, idlinea) VALUES (?, ?)"); + foreach ($idlinee as $idlinea) { + $stmt->execute([$idmatrice, $idlinea]); + } + } + + $pdo->commit(); + + echo json_encode(['success' => true, 'message' => 'Associazioni aggiornate']); +} catch (Throwable $e) { + if (isset($pdo) && $pdo->inTransaction()) $pdo->rollBack(); + echo json_encode(['success' => false, 'message' => 'Server error']); +} diff --git a/public/userarea/save_matrice_mescole.php b/public/userarea/save_matrice_mescole.php index b6fdfda..9579be4 100644 --- a/public/userarea/save_matrice_mescole.php +++ b/public/userarea/save_matrice_mescole.php @@ -1,27 +1,42 @@ false, 'message' => 'Invalid idmatrice']); + exit; + } + if (!is_array($idmescole)) $idmescole = []; + + // normalizza a int e rimuovi duplicati + $idmescole = array_values(array_unique(array_filter(array_map('intval', $idmescole), fn($v) => $v > 0))); $db = DBHandlerSelect::getInstance(); $pdo = $db->getConnection(); - // Rimuove tutte le precedenti associazioni - $pdo->prepare("DELETE FROM matrice_mescole WHERE idmatrice = ?")->execute([$idMatrice]); + $pdo->beginTransaction(); - // Inserisce le nuove - if (!empty($mescole)) { - $stmt = $pdo->prepare("INSERT INTO matrice_mescole (idmatrice, idmescola) VALUES (?, ?)"); - foreach ($mescole as $idMescola) { - $stmt->execute([$idMatrice, $idMescola]); + // rimuovi vecchie associazioni + $stmt = $pdo->prepare("DELETE FROM matrici_mescole WHERE idmatrice = ?"); + $stmt->execute([$idmatrice]); + + // inserisci nuove + if (!empty($idmescole)) { + $stmt = $pdo->prepare("INSERT INTO matrici_mescole (idmatrice, idmescola) VALUES (?, ?)"); + foreach ($idmescole as $idmescola) { + $stmt->execute([$idmatrice, $idmescola]); } } - echo json_encode(['success' => true, 'message' => 'Associazioni mescole aggiornate.']); -} catch (Exception $e) { - echo json_encode(['success' => false, 'message' => 'Errore: ' . $e->getMessage()]); + $pdo->commit(); + + echo json_encode(['success' => true, 'message' => 'Associazioni aggiornate']); +} catch (Throwable $e) { + if (isset($pdo) && $pdo->inTransaction()) $pdo->rollBack(); + echo json_encode(['success' => false, 'message' => 'Server error']); }