status added

This commit is contained in:
Claudio 2025-11-22 20:34:51 +01:00
parent 779821a08b
commit 6f3b933a71
6 changed files with 514 additions and 124 deletions

View File

@ -0,0 +1,37 @@
<?php
include('include/headscript.php');
header('Content-Type: application/json');
try {
$db = DBHandlerSelect::getInstance();
$pdo = $db->getConnection();
$id = intval($_GET['id'] ?? 0);
if ($id <= 0) {
echo json_encode(['success' => false, 'message' => 'ID non valido']);
exit;
}
// Verifica se status è usato in produzione
$check = $pdo->prepare("SELECT COUNT(*) FROM productiondata WHERE id_status = :id");
$check->execute([':id' => $id]);
$count = $check->fetchColumn();
if ($count > 0) {
echo json_encode([
'success' => false,
'message' => "Impossibile eliminare: lo status è utilizzato in $count record di produzione."
]);
exit;
}
// Eliminazione
$stmt = $pdo->prepare("DELETE FROM production_status WHERE id = :id");
$stmt->execute([':id' => $id]);
echo json_encode(['success' => true]);
} catch (Exception $e) {
echo json_encode(['success' => false, 'message' => $e->getMessage()]);
}

View File

@ -0,0 +1,48 @@
<?php
include('include/headscript.php');
header('Content-Type: application/json');
try {
$db = DBHandlerSelect::getInstance();
$pdo = $db->getConnection();
// Validazione
$id = intval($_POST['id'] ?? 0);
$nome = trim($_POST['nome'] ?? '');
$ordinamento = intval($_POST['ordinamento'] ?? 0);
$badge = $_POST['badge_color'] ?? '#6c757d';
$line = $_POST['line_color'] ?? '#e9ecef';
if ($id <= 0) {
echo json_encode(['success' => false, 'message' => 'ID non valido']);
exit;
}
if ($nome === '') {
echo json_encode(['success' => false, 'message' => 'Il nome è obbligatorio']);
exit;
}
// Update
$stmt = $pdo->prepare("
UPDATE production_status
SET nome = :nome,
ordinamento = :ordinamento,
badge_color = :badge,
line_color = :line
WHERE id = :id
");
$stmt->execute([
':nome' => $nome,
':ordinamento' => $ordinamento,
':badge' => $badge,
':line' => $line,
':id' => $id
]);
echo json_encode(['success' => true]);
} catch (Exception $e) {
echo json_encode(['success' => false, 'message' => $e->getMessage()]);
}

View File

@ -276,20 +276,21 @@
</button>
</div>
<!-- ===== TERZA RIGA (solo 2 bottoni centrati) =====
<!-- ===== TERZA RIGA (solo 2 bottoni centrati) ===== -->
<div class="dashboard-grid-bottom">
<button class="dash-btn btn-inserisci" onclick="location.href='production_add.php'">
<div class="dash-icon"></div>
<div>Inserisci Dati Produzione</div>
<button class="dash-btn btn-inserisci btn-inserisci-status" onclick="location.href='production_status.php'">
<div class="dash-icon">📋</div>
<div>Status</div>
</button>
<button class="dash-btn btn-visualizza" onclick="location.href='production_all.php'">
<!-- <button class="dash-btn btn-visualizza" onclick="location.href='production_all.php'">
<div class="dash-icon">📊</div>
<div>Riepilogo Produzione</div>
</button>
<div></div>
</div> -->
</button> -->
<div></div>
</div>
</div>
</div>

View File

@ -20,9 +20,7 @@ $statusProgrammatoId = $statusProgrammato['id'];
$statusProduzioneId = $statusProduzione['id'];
$statusPausaId = $statusPausa['id'];
// --- DATA E LINEA SELEZIONATE ---
$selected_date = $_GET['date'] ?? date('Y-m-d');
$selected_line = $_GET['line'] ?? '';
// --- AVVIO / RIPRESA PRODUZIONE ---
if ($_SERVER['REQUEST_METHOD'] === 'POST' && !empty($_POST['start_production'])) {
@ -174,64 +172,13 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && !empty($_POST['save_final_data']))
exit;
}
// --- AJAX: carica record giorno successivo ---
if (!empty($_GET['ajax_next'])) {
$date = $_GET['date'] ?? date('Y-m-d');
$lineRaw = $_GET['line'] ?? '';
$lineArray = $lineRaw !== '' ? explode(',', $lineRaw) : [];
$sql = "SELECT
p.*,
m.nome AS matrice,
ms.nome AS mescola,
l.name AS linea,
c.nome AS cliente,
s.nome AS status_nome,
s.badge_color,
s.line_color,
p.tempo_totale_produzione
FROM productiondata p
LEFT JOIN matrice m ON p.idmatrice = m.id
LEFT JOIN mescole ms ON p.idmescola = ms.id
LEFT JOIN production_lines l ON p.id_linea = l.id
LEFT JOIN clients c ON p.id_cliente = c.id
LEFT JOIN production_status s ON p.id_status = s.id
WHERE p.data_produzione = :date
AND p.id_status IN (:programmato, :produzione, :pausa)"
. (!empty($lineArray) ? " AND p.id_linea IN (" . implode(',', array_map('intval', $lineArray)) . ")" : "")
. " ORDER BY l.line_number, p.Data";
$params = [
':date' => $date,
':programmato' => $statusProgrammatoId,
':produzione' => $statusProduzioneId,
':pausa' => $statusPausaId
];
$stmt = $pdo->prepare($sql);
$stmt->execute($params);
$recordsNext = $stmt->fetchAll();
if (empty($recordsNext)) {
exit; // ritorna vuoto
}
foreach ($recordsNext as $r) {
include __DIR__ . "/render_production_card.php";
}
exit;
}
// --- AJAX PRINCIPALE: carica i record della data selezionata ---
if (!empty($_GET['ajax'])) {
$date = $_GET['date'] ?? date('Y-m-d');
$lineRaw = $_GET['line'] ?? '';
$lineArray = $lineRaw !== '' ? explode(',', $lineRaw) : [];
// --- RECORD IN PRODUZIONE (2,7,8)
$sql = "SELECT
p.*,
m.nome AS matrice,
@ -248,34 +195,55 @@ if (!empty($_GET['ajax'])) {
LEFT JOIN production_lines l ON p.id_linea = l.id
LEFT JOIN clients c ON p.id_cliente = c.id
LEFT JOIN production_status s ON p.id_status = s.id
WHERE p.data_produzione = :date
AND p.id_status IN (:programmato, :produzione, :pausa)"
. (!empty($lineArray) ? " AND p.id_linea IN (" . implode(',', array_map('intval', $lineArray)) . ")" : "")
. " ORDER BY l.line_number, p.Data";
$params = [
':date' => $date,
':programmato' => $statusProgrammatoId,
':produzione' => $statusProduzioneId,
':pausa' => $statusPausaId
];
WHERE p.id_status IN (2, 7, 8)
" . (!empty($lineArray) ? " AND p.id_linea IN (" . implode(',', array_map('intval', $lineArray)) . ")" : "") . "
ORDER BY l.line_number, p.Data";
$stmt = $pdo->prepare($sql);
$stmt->execute($params);
$stmt->execute();
$records = $stmt->fetchAll();
if (empty($records)) {
exit;
}
foreach ($records as $r) {
include __DIR__ . "/render_production_card.php";
}
// --- RECORD IN STATO 6 ORDINATI PER PRIORITY
$sql2 = "SELECT
p.*,
m.nome AS matrice,
ms.nome AS mescola,
l.name AS linea,
c.nome AS cliente,
s.nome AS status_nome,
s.badge_color,
s.line_color,
p.tempo_totale_produzione
FROM productiondata p
LEFT JOIN matrice m ON p.idmatrice = m.id
LEFT JOIN mescole ms ON p.idmescola = ms.id
LEFT JOIN production_lines l ON p.id_linea = l.id
LEFT JOIN clients c ON p.id_cliente = c.id
LEFT JOIN production_status s ON p.id_status = s.id
WHERE p.id_status = 6
" . (!empty($lineArray) ? " AND p.id_linea IN (" . implode(',', array_map('intval', $lineArray)) . ")" : "") . "
ORDER BY p.priority ASC";
$stmt2 = $pdo->prepare($sql2);
$stmt2->execute();
$recordsPriority = $stmt2->fetchAll();
if (!empty($recordsPriority)) {
echo '<div style="margin:20px 0; font-size:1.3rem; font-weight:700; color:#1e40af;">Programmato (in ordine di priorità)</div>';
foreach ($recordsPriority as $r) {
include __DIR__ . "/render_production_card.php";
}
}
exit;
}
?>
<!doctype html>
@ -287,7 +255,7 @@ if (!empty($_GET['ajax'])) {
<title>Linea Produzione - Tablet</title>
<?php include('cssinclude.php'); ?>
<link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/flatpickr/dist/flatpickr.min.css">
<style>
* {
box-sizing: border-box;
@ -757,10 +725,6 @@ if (!empty($_GET['ajax'])) {
</div>
<div class="filters">
<div class="filter-group">
<label for="filterDate">Giornata</label>
<input type="text" id="filterDate" placeholder="gg/mm/aaaa">
</div>
<div class="filter-group">
<label>Linee</label>
@ -877,7 +841,7 @@ if (!empty($_GET['ajax'])) {
</div>
</div>
</div>
>
@ -1006,17 +970,11 @@ if (!empty($_GET['ajax'])) {
$("#photoModal").removeClass("active");
});
</script>
<script src="https://cdn.jsdelivr.net/npm/flatpickr"></script>
<?php include('jsinclude.php'); ?>
<script>
$(function() {
const datePicker = flatpickr("#filterDate", {
dateFormat: "d/m/Y",
defaultDate: "<?= date('d/m/Y') ?>",
onChange: loadRecords
});
$('#filterLine').on('change', loadRecords);
const beep = $('#beepSound')[0];
let timers = {};
@ -1067,46 +1025,18 @@ if (!empty($_GET['ajax'])) {
// --- CARICA RECORD ---
function loadRecords() {
const date = datePicker.selectedDates[0];
const isoDate = date ? new Date(date.getTime() - (date.getTimezoneOffset() * 60000)).toISOString().split('T')[0] : '<?= date('Y-m-d') ?>';
const line = $('#filterLine').val();
$('#recordsContainer').html('<div class="text-center p-5"><i class="bi bi-hourglass-split" style="font-size:2.5rem;color:#94a3b8;"></i></div>');
const line = $('#filterLine').val();
$.get('', {
ajax: 1,
date: isoDate,
line: line
}, function(html) {
// Il primo HTML (oggi / data selezionata)
let htmlOggi = html;
// Ora carichiamo DOMANI
const dateObj = new Date(isoDate);
dateObj.setDate(dateObj.getDate() + 1);
const tomorrow = dateObj.toISOString().split('T')[0];
$.get('', {
ajax_next: 1,
date: tomorrow,
line: line
}, function(htmlNext) {
let titoloNext = `
<div style="margin:20px 0; font-size:1.4rem; font-weight:700; color:#1e40af;">
Programmazione giorno successivo (${formatItalianDate(tomorrow)})
</div>
`;
$('#recordsContainer').html(
htmlOggi +
(htmlNext.trim() !== '' ? titoloNext + htmlNext : '')
);
startAllTimers();
setupEventHandlers();
});
// 🔥 INSERIRE LHTML NEL CONTAINER
$('#recordsContainer').html(html);
startAllTimers();
setupEventHandlers();

View File

@ -0,0 +1,337 @@
<?php include('include/headscript.php'); ?>
<!doctype html>
<html lang="it">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" href="assets/images/favicon-32x32.png" type="image/png" />
<?php include('cssinclude.php'); ?>
<title>Gestione Status Produzione - <?= htmlspecialchars($titlewebsite, ENT_QUOTES, 'UTF-8'); ?></title>
<!-- jQuery, Bootstrap, DataTables, 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>
<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>
<style>
body {
font-size: 1.05rem;
background: #f8fafc;
}
.card {
border-radius: 16px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
}
.table thead {
background-color: #cfe3ff;
color: #1f2d3d;
text-align: center;
}
th,
td {
vertical-align: middle;
text-align: center;
}
.btn-action {
border: none;
background: transparent;
cursor: pointer;
font-size: 1.3rem;
}
.btn-action.edit {
color: #0d6efd;
}
.btn-action.delete {
color: #dc3545;
}
.btn-action:hover {
transform: scale(1.15);
}
.color-preview {
width: 45px;
height: 22px;
border-radius: 6px;
border: 1px solid #999;
margin: auto;
}
.back-dashboard {
background-color: #cfe3ff !important;
color: #1f2d3d !important;
border-radius: 10px;
font-weight: 600;
padding: 10px 18px;
}
</style>
</head>
<body>
<div class="wrapper">
<?php include('include/navbar.php'); ?>
<?php include('include/topbar.php'); ?>
<div class="page-wrapper">
<div class="page-content">
<div class="card p-3">
<div class="card-header d-flex justify-content-between align-items-center">
<h5 class="mb-0 text-center w-100">Gestione Status Produzione</h5>
<button type="button"
class="btn back-dashboard position-absolute end-0 me-3"
onclick="location.href='production_dashboard.php'">
↩️ Torna alla Dashboard
</button>
</div>
<div class="card-body">
<div class="d-flex justify-content-between align-items-center mb-3">
<h6 class="fw-semibold mb-0">Elenco Status</h6>
<button class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#addStatusModal">
Aggiungi Status
</button>
</div>
<div class="table-responsive">
<table id="tabStatus" class="table table-striped align-middle">
<thead>
<tr>
<th>ID</th>
<th>Nome</th>
<th>Ordinamento</th>
<th>Colore Badge</th>
<th>Colore Linea</th>
<th>Azioni</th>
</tr>
</thead>
<tbody>
<?php
$db = DBHandlerSelect::getInstance();
$pdo = $db->getConnection();
$stmt = $pdo->query("SELECT * FROM production_status ORDER BY ordinamento ASC");
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)):
?>
<tr>
<td><?= $row['id'] ?></td>
<td><?= htmlspecialchars($row['nome']) ?></td>
<td><?= $row['ordinamento'] ?></td>
<td>
<div class="color-preview" style="background: <?= $row['badge_color'] ?>"></div>
<small><?= $row['badge_color'] ?></small>
</td>
<td>
<div class="color-preview" style="background: <?= $row['line_color'] ?>"></div>
<small><?= $row['line_color'] ?></small>
</td>
<td>
<button class="btn-action edit" title="Modifica"
data-id="<?= $row['id'] ?>"
data-nome="<?= htmlspecialchars($row['nome'], ENT_QUOTES) ?>"
data-ord="<?= $row['ordinamento'] ?>"
data-badge="<?= $row['badge_color'] ?>"
data-line="<?= $row['line_color'] ?>">
<i class="fas fa-edit"></i>
</button>
<button class="btn-action delete" title="Elimina"
data-id="<?= $row['id'] ?>">
<i class="fas fa-trash"></i>
</button>
</td>
</tr>
<?php endwhile; ?>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
<?php include('include/footer.php'); ?>
</div>
<!-- MODALE AGGIUNTA -->
<div class="modal fade" id="addStatusModal" tabindex="-1">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header" style="background:#cfe3ff">
<h5 class="modal-title">Aggiungi Nuovo Status</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<form id="addStatusForm">
<div class="modal-body">
<label class="fw-semibold">Nome Status</label>
<input type="text" name="nome" class="form-control mb-3" required>
<label class="fw-semibold">Ordinamento</label>
<input type="number" name="ordinamento" class="form-control mb-3" required>
<label class="fw-semibold">Colore Badge</label>
<input type="color" name="badge_color" class="form-control form-control-color mb-3" value="#6c757d">
<label class="fw-semibold">Colore Linea</label>
<input type="color" name="line_color" class="form-control form-control-color mb-3" value="#e9ecef">
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-primary">💾 Salva</button>
</div>
</form>
</div>
</div>
</div>
<!-- MODALE MODIFICA -->
<div class="modal fade" id="editStatusModal" tabindex="-1">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header" style="background:#cfe3ff">
<h5 class="modal-title">Modifica Status</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<form id="editStatusForm">
<div class="modal-body">
<input type="hidden" name="id" id="edit_id">
<label class="fw-semibold">Nome Status</label>
<input type="text" name="nome" id="edit_nome" class="form-control mb-3" required>
<label class="fw-semibold">Ordinamento</label>
<input type="number" name="ordinamento" id="edit_ordinamento" class="form-control mb-3" required>
<label class="fw-semibold">Colore Badge</label>
<input type="color" name="badge_color" id="edit_badge" class="form-control form-control-color mb-3">
<label class="fw-semibold">Colore Linea</label>
<input type="color" name="line_color" id="edit_line" class="form-control form-control-color mb-3">
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-primary">💾 Aggiorna</button>
</div>
</form>
</div>
</div>
</div>
<script>
$(document).ready(function() {
$('#tabStatus').DataTable({
order: [
[2, 'asc']
],
pageLength: 50,
language: {
url: 'https://cdn.datatables.net/plug-ins/1.13.6/i18n/it-IT.json'
}
});
// SALVATAGGIO NUOVO STATUS
$("#addStatusForm").on("submit", function(e) {
e.preventDefault();
fetch("save_status.php", {
method: "POST",
body: new FormData(this)
})
.then(r => r.json())
.then(d => {
if (d.success) {
Swal.fire("Salvato!", "Nuovo status aggiunto", "success")
.then(() => location.reload());
} else Swal.fire("Errore", d.message, "error");
});
});
// ✏️ APRI MODALE MODIFICA
$(document).on("click", ".edit", function() {
$("#edit_id").val($(this).data("id"));
$("#edit_nome").val($(this).data("nome"));
$("#edit_ordinamento").val($(this).data("ord"));
$("#edit_badge").val($(this).data("badge"));
$("#edit_line").val($(this).data("line"));
$("#editStatusModal").modal("show");
});
// 💾 SALVA MODIFICA STATUS
$("#editStatusForm").on("submit", function(e) {
e.preventDefault();
fetch("edit_status.php", {
method: "POST",
body: new FormData(this)
})
.then(r => r.json())
.then(d => {
if (d.success) {
Swal.fire("Aggiornato!", "Lo status è stato modificato.", "success")
.then(() => location.reload());
} else Swal.fire("Errore", d.message, "error");
});
});
// 🗑️ ELIMINA STATUS
$(document).on("click", ".delete", function() {
const id = $(this).data("id");
Swal.fire({
title: "Eliminare lo status?",
text: "L'azione è irreversibile.",
icon: "warning",
showCancelButton: true,
confirmButtonText: "Sì, elimina",
cancelButtonText: "Annulla"
}).then(result => {
if (result.isConfirmed) {
fetch("delete_status.php?id=" + id)
.then(r => r.json())
.then(d => {
if (d.success) {
Swal.fire("Eliminato!", "Status rimosso.", "success")
.then(() => location.reload());
} else Swal.fire("Errore", d.message, "error");
});
}
});
});
});
</script>
</body>
</html>

View File

@ -0,0 +1,37 @@
<?php
include('include/headscript.php');
header('Content-Type: application/json');
try {
$db = DBHandlerSelect::getInstance();
$pdo = $db->getConnection();
// Validazione campi
$nome = trim($_POST['nome'] ?? '');
$ordinamento = intval($_POST['ordinamento'] ?? 0);
$badge = $_POST['badge_color'] ?? '#6c757d';
$line = $_POST['line_color'] ?? '#e9ecef';
if ($nome === '') {
echo json_encode(['success' => false, 'message' => 'Il nome è obbligatorio']);
exit;
}
// Inserimento
$stmt = $pdo->prepare("
INSERT INTO production_status (nome, ordinamento, badge_color, line_color)
VALUES (:nome, :ordinamento, :badge, :line)
");
$stmt->execute([
':nome' => $nome,
':ordinamento' => $ordinamento,
':badge' => $badge,
':line' => $line,
]);
echo json_encode(['success' => true]);
} catch (Exception $e) {
echo json_encode(['success' => false, 'message' => $e->getMessage()]);
}