fixed matrici

This commit is contained in:
Claudio 2026-01-27 09:57:47 +01:00
parent 51cca3448a
commit 1edf7b7239
5 changed files with 483 additions and 41 deletions

View File

@ -0,0 +1,36 @@
<?php
include('include/headscript.php');
header('Content-Type: application/json; charset=utf-8');
try {
$idmatrice = (int)($_GET['id'] ?? 0);
if ($idmatrice <= 0) {
echo json_encode(['success' => 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']);
}

View File

@ -0,0 +1,35 @@
<?php
include('include/headscript.php');
header('Content-Type: application/json; charset=utf-8');
try {
$idmatrice = (int)($_GET['id'] ?? 0);
if ($idmatrice <= 0) {
echo json_encode(['success' => 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']);
}

View File

@ -11,13 +11,12 @@
<!-- jQuery, Bootstrap, SweetAlert -->
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
<!-- DataTables -->
<link rel="stylesheet" href="https://cdn.datatables.net/1.13.6/css/dataTables.bootstrap5.min.css">
<script src="https://cdn.datatables.net/1.13.6/js/jquery.dataTables.min.js"></script>
<script src="https://cdn.datatables.net/1.13.6/js/dataTables.bootstrap5.min.js"></script>
<!-- Select2 -->
<link href="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/css/select2.min.css" rel="stylesheet" />
@ -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 @@
<th>Foto</th>
<th>Nome</th>
<th>Cliente</th>
<th>Data</th>
<th>Linee</th>
<th>Azioni</th>
</tr>
</thead>
@ -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 @@
. "</td>";
// colonna DATA
echo "<td>{$dataIT}</td>";
// colonna LINEE
$lineeTxt = $row['linee_associate'] ?? '—';
$mescoleTxt = $row['mescole_associate'] ?? '';
$mescoleCount = (int)($row['mescole_count'] ?? 0);
$btnMescole = '';
if ($mescoleCount > 0) {
$btnMescole = " <button type='button'
class='btn btn-sm btn-outline-secondary ms-2 show-mescole'
data-nome='" . htmlspecialchars($row['nome'], ENT_QUOTES) . "'
data-mescole='" . htmlspecialchars($mescoleTxt, ENT_QUOTES) . "'
data-bs-toggle='tooltip' data-bs-title='Vedi mescole associate'>
<i class='fa-solid fa-flask'></i>
</button>";
}
echo "<td title='" . htmlspecialchars($lineeTxt, ENT_QUOTES) . "'>"
. htmlspecialchars($lineeTxt)
. $btnMescole
. "</td>";
// colonna AZIONI
echo "<td>
<button class='action-btn edit'
data-id='{$row['id']}'
data-nome='" . htmlspecialchars($row['nome'], ENT_QUOTES) . "'
data-cliente='" . htmlspecialchars($row['cliente'], ENT_QUOTES) . "'
data-data='{$dataIT}'>
<i class='fa-solid fa-pen-to-square'></i>
</button>
<button class='action-btn edit'
data-id='{$row['id']}'
data-nome='" . htmlspecialchars($row['nome'], ENT_QUOTES) . "'
data-cliente='" . htmlspecialchars($row['cliente'], ENT_QUOTES) . "'
data-data='{$dataIT}'
data-bs-toggle='tooltip' data-bs-title='Modifica'>
<i class='fa-solid fa-pen-to-square'></i>
</button>
<button class='action-btn delete' data-id='{$row['id']}'>
<i class='fa-solid fa-trash'></i>
</button>
<button class='action-btn delete'
data-id='{$row['id']}'
data-bs-toggle='tooltip' data-bs-title='Elimina'>
<i class='fa-solid fa-trash'></i>
</button>
<button class='action-btn linee' data-id='{$row['id']}' data-nome='" . htmlspecialchars($row['nome'], ENT_QUOTES) . "'>
<i class='fa-solid fa-sitemap'></i>
</button>
<button class='action-btn linee'
data-id='{$row['id']}'
data-nome='" . htmlspecialchars($row['nome'], ENT_QUOTES) . "'
data-bs-toggle='tooltip' data-bs-title='Linee associate'>
<i class='fa-solid fa-sitemap'></i>
</button>
<button class='action-btn mescole'
data-id='{$row['id']}'
data-nome='" . htmlspecialchars($row['nome'], ENT_QUOTES) . "'
data-bs-toggle='tooltip' data-bs-title='Mescole associate'>
<i class='fa-solid fa-flask'></i>
</button>
</td>";
<button class='action-btn mescole' data-id='{$row['id']}' data-nome='" . htmlspecialchars($row['nome'], ENT_QUOTES) . "'>
<i class='fa-solid fa-flask'></i>
</button>
</td>";
echo "</tr>";
}
@ -382,6 +439,70 @@
</div>
</div>
</div>
<!-- MODALE LINEE ASSOCIATE -->
<div class="modal fade" id="matriceLineeModal" tabindex="-1" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header" style="background-color:#b9ebc7;">
<h5 class="modal-title">Linee associate</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<input type="hidden" id="ml_idmatrice">
<div class="mb-2">
<div class="fw-semibold" id="ml_matrice_name" style="color:#1f2d3d;"></div>
<small class="text-muted">Seleziona una o più linee di produzione</small>
</div>
<div class="mb-3">
<label class="fw-semibold">Linee</label>
<select id="ml_linee" class="form-select" multiple="multiple" style="width:100%;"></select>
</div>
<div class="text-center">
<button type="button" class="btn btn-add" id="ml_save_btn">💾 Salva Linee</button>
</div>
</div>
</div>
</div>
</div>
<!-- MODALE MESCOLE ASSOCIATE -->
<div class="modal fade" id="matriceMescoleModal" tabindex="-1" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header" style="background-color:#b9ebc7;">
<h5 class="modal-title">Mescole associate</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<input type="hidden" id="mm_idmatrice">
<div class="mb-2">
<div class="fw-semibold" id="mm_matrice_name" style="color:#1f2d3d;"></div>
<small class="text-muted">Seleziona una o più mescole</small>
</div>
<div class="mb-3">
<label class="fw-semibold">Mescole</label>
<select id="mm_mescole" class="form-select" multiple="multiple" style="width:100%;"></select>
</div>
<div class="text-center">
<button type="button" class="btn btn-add" id="mm_save_btn">💾 Salva Mescole</button>
</div>
</div>
</div>
</div>
</div>
<?php include('jsinclude.php'); ?>
@ -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("<span class='text-muted'>Nessuna mescola associata</span>");
} else {
// elenco in badge
const items = mescole.split(',').map(s => s.trim()).filter(Boolean);
$("#mlm_list").html(items.map(x => `<span class="badge bg-secondary me-1 mb-1">${x}</span>`).join(''));
}
const modal = new bootstrap.Modal(document.getElementById('mescoleListModal'));
modal.show();
});
});
@ -523,6 +818,24 @@
<img id="bigImg" src=""
style="max-width:70vw; max-height:90vh; border-radius:12px;">
</div>
<!-- MODALE LISTA MESCOLE ASSOCIATE (READ-ONLY) -->
<div class="modal fade" id="mescoleListModal" tabindex="-1" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header" style="background-color:#b9ebc7;">
<h5 class="modal-title">Mescole associate</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<div class="fw-semibold mb-2" id="mlm_matrice_name" style="color:#1f2d3d;"></div>
<div id="mlm_list" class="text-muted"></div>
</div>
</div>
</div>
</div>
</body>

View File

@ -0,0 +1,43 @@
<?php
include('include/headscript.php');
header('Content-Type: application/json; charset=utf-8');
try {
$idmatrice = (int)($_POST['idmatrice'] ?? 0);
$raw = $_POST['idlinee'] ?? '[]';
$idlinee = json_decode($raw, true);
if ($idmatrice <= 0) {
echo json_encode(['success' => 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']);
}

View File

@ -1,27 +1,42 @@
<?php
include('../class/db-functions.php');
header('Content-Type: application/json');
include('include/headscript.php');
header('Content-Type: application/json; charset=utf-8');
try {
$data = json_decode(file_get_contents('php://input'), true);
$idMatrice = intval($data['id']);
$mescole = $data['mescole'] ?? [];
$idmatrice = (int)($_POST['idmatrice'] ?? 0);
$raw = $_POST['idmescole'] ?? '[]';
$idmescole = json_decode($raw, true);
if ($idmatrice <= 0) {
echo json_encode(['success' => 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']);
}