diff --git a/public/userarea/delete_pause_reason.php b/public/userarea/delete_pause_reason.php new file mode 100644 index 0000000..473939b --- /dev/null +++ b/public/userarea/delete_pause_reason.php @@ -0,0 +1,35 @@ +getConnection(); + +$id = (int)($_GET['id'] ?? 0); + +if ($id <= 0) { + echo json_encode(['success' => false, 'message' => 'ID non valido.']); + exit; +} + +try { + // Verifica se è usata in production_pauses + $check = $pdo->prepare("SELECT COUNT(*) FROM production_pauses WHERE reason_id = :id"); + $check->execute([':id' => $id]); + $used = $check->fetchColumn(); + + if ($used > 0) { + echo json_encode([ + 'success' => false, + 'message' => 'Impossibile eliminare: la causa è utilizzata in una o più pause.' + ]); + exit; + } + + // Elimina + $stmt = $pdo->prepare("DELETE FROM pause_reasons WHERE id = :id"); + $stmt->execute([':id' => $id]); + + echo json_encode(['success' => true]); +} catch (Exception $e) { + echo json_encode(['success' => false, 'message' => $e->getMessage()]); +} diff --git a/public/userarea/edit_pause_reason.php b/public/userarea/edit_pause_reason.php new file mode 100644 index 0000000..748b92b --- /dev/null +++ b/public/userarea/edit_pause_reason.php @@ -0,0 +1,40 @@ +getConnection(); + +$id = (int)($_POST['id'] ?? 0); +$name = trim($_POST['name'] ?? ''); +$description = trim($_POST['description'] ?? ''); +$is_problem = isset($_POST['is_problem']) ? (int)$_POST['is_problem'] : 0; + +if ($id <= 0) { + echo json_encode(['success' => false, 'message' => 'ID non valido.']); + exit; +} +if ($name === '') { + echo json_encode(['success' => false, 'message' => 'Il nome è obbligatorio.']); + exit; +} + +try { + $stmt = $pdo->prepare(" + UPDATE pause_reasons + SET name = :name, + description = :description, + is_problem = :is_problem + WHERE id = :id + "); + + $stmt->execute([ + ':name' => $name, + ':description' => $description !== '' ? $description : null, + ':is_problem' => $is_problem, + ':id' => $id + ]); + + echo json_encode(['success' => true]); +} catch (Exception $e) { + echo json_encode(['success' => false, 'message' => $e->getMessage()]); +} diff --git a/public/userarea/production_dashboard.php b/public/userarea/production_dashboard.php index 9e7da12..5f3a6ea 100644 --- a/public/userarea/production_dashboard.php +++ b/public/userarea/production_dashboard.php @@ -191,6 +191,18 @@ font-size: 2.6rem; } } + + .btn-problem { + background-color: #ef4444 !important; + /* rosso brillante */ + color: #ffffff !important; + border-radius: 12px; + } + + .btn-problem:hover { + background-color: #dc2626 !important; + /* rosso scuro hover */ + } @@ -285,10 +297,11 @@ - + +
diff --git a/public/userarea/production_line_view2.php b/public/userarea/production_line_view2.php new file mode 100644 index 0000000..e0492b9 --- /dev/null +++ b/public/userarea/production_line_view2.php @@ -0,0 +1,1557 @@ +getConnection(); + +// --- LISTE LINEE --- +$linee = $pdo->query("SELECT id, name, color FROM production_lines ORDER BY line_number")->fetchAll(); + +// --- STATUS DINAMICI --- +$statusProgrammato = $pdo->query("SELECT id, nome, badge_color, line_color FROM production_status WHERE id = 6 LIMIT 1")->fetch(); +$statusProduzione = $pdo->query("SELECT id, nome, badge_color, line_color FROM production_status WHERE id = 2 LIMIT 1")->fetch(); +$statusPausa = $pdo->query("SELECT id, nome, badge_color, line_color FROM production_status WHERE id = 7 LIMIT 1")->fetch(); +$statusQualita = $pdo->query("SELECT id FROM production_status WHERE id = 3 LIMIT 1")->fetchColumn(); + +if (!$statusProgrammato || !$statusProduzione || !$statusPausa || !$statusQualita) { + die("Errore: uno o più status non trovati in production_status"); +} + +$statusProgrammatoId = $statusProgrammato['id']; +$statusProduzioneId = $statusProduzione['id']; +$statusPausaId = $statusPausa['id']; + +// --- PAUSE REASONS --- +$pauseReasons = $pdo->query("SELECT id, name, is_problem FROM pause_reasons ORDER BY name")->fetchAll(); + + +// --- AVVIO / RIPRESA PRODUZIONE --- +if ($_SERVER['REQUEST_METHOD'] === 'POST' && !empty($_POST['start_production'])) { + $id = (int)$_POST['id']; + + try { + // 1) Leggo stato attuale + $sql = "SELECT id_status FROM productiondata WHERE id = :id LIMIT 1"; + $stmt = $pdo->prepare($sql); + $stmt->execute(['id' => $id]); + $currentStatus = $stmt->fetchColumn(); + + if ($currentStatus === false) { + echo json_encode(['success' => false, 'msg' => 'Record produzione non trovato.']); + exit; + } + + // 2) Primo avvio: da PROGRAMMATO (6) → PRODUZIONE (2) + set start_time + if ((int)$currentStatus === (int)$statusProgrammatoId) { + + $sqlUpdate = "UPDATE productiondata + SET id_status = :status, + start_time = UTC_TIMESTAMP(), + end_time = NULL + WHERE id = :id AND id_status = :programmato"; + + $stmtUpdate = $pdo->prepare($sqlUpdate); + $stmtUpdate->execute([ + 'status' => $statusProduzioneId, + 'id' => $id, + 'programmato' => $statusProgrammatoId + ]); + + // 3) Ripresa: da PAUSA (7) → PRODUZIONE (2) **senza toccare start_time** + } elseif ((int)$currentStatus === (int)$statusPausaId) { + + $sqlUpdate = "UPDATE productiondata + SET id_status = :status, + end_time = NULL + WHERE id = :id AND id_status = :pausa"; + + $stmtUpdate = $pdo->prepare($sqlUpdate); + $stmtUpdate->execute([ + 'status' => $statusProduzioneId, + 'id' => $id, + 'pausa' => $statusPausaId + ]); + } else { + echo json_encode([ + 'success' => false, + 'msg' => 'Lo stato corrente non consente avvio/ripresa (stato id: ' . $currentStatus . ')' + ]); + exit; + } + + echo json_encode(['success' => true]); + } catch (Exception $e) { + echo json_encode(['success' => false, 'msg' => $e->getMessage()]); + } + exit; +} + + + +// --- PAUSA PRODUZIONE (crea record in production_pauses + cambia stato) --- +// --- PAUSA PRODUZIONE (crea record in production_pauses + cambia stato) --- +if ($_SERVER['REQUEST_METHOD'] === 'POST' && !empty($_POST['pause_production'])) { + $id = (int)$_POST['id']; + $reasonId = isset($_POST['reason_id']) ? (int)$_POST['reason_id'] : 0; + $note = trim($_POST['note'] ?? ''); + + try { + + if ($reasonId <= 0) { + echo json_encode(['success' => false, 'msg' => 'Motivo pausa non valido.']); + exit; + } + + // Leggo se il motivo è "problema" oppure pausa normale + $sql = "SELECT is_problem FROM pause_reasons WHERE id = :id LIMIT 1"; + $stmt = $pdo->prepare($sql); + $stmt->execute(['id' => $reasonId]); + $isProblem = $stmt->fetchColumn(); + + if ($isProblem === false) { + echo json_encode(['success' => false, 'msg' => 'Motivo pausa non trovato.']); + exit; + } + + $isProblem = (int)$isProblem; + // ❌ PRIMA – sbagliato per la tua logica: + // $nextStatus = $isProblem ? 8 : $statusPausaId; // 8 = Problema in produzione + + // ✅ ORA – in PAUSA lo stato è SEMPRE pausa (7) + $nextStatus = $statusPausaId; + // Aggiorno lo stato sulla produzione SOLO se è in produzione (id_status = produzione) + $sql = "UPDATE productiondata + SET id_status = :status, + note_operatore = :note + WHERE id = :id AND id_status = :produzione"; + $stmtUpdate = $pdo->prepare($sql); + $stmtUpdate->execute([ + 'status' => $nextStatus, + 'note' => $note ?: null, + 'id' => $id, + 'produzione' => $statusProduzioneId + ]); + + // Se effettivamente ho cambiato lo stato, registro la pausa + if ($stmtUpdate->rowCount() > 0) { + $sqlPause = "INSERT INTO production_pauses + (id_production, reason_id, start_pause, note) + VALUES (:id_production, :reason_id, UTC_TIMESTAMP(), :note)"; + $stmtPause = $pdo->prepare($sqlPause); + $stmtPause->execute([ + 'id_production' => $id, + 'reason_id' => $reasonId, + 'note' => $note ?: null + ]); + } + + echo json_encode(['success' => true]); + } catch (Exception $e) { + echo json_encode(['success' => false, 'msg' => $e->getMessage()]); + } + exit; +} + + + +// --- STOP PRODUZIONE (vai a Qualità + salva tempo finale) --- +if ($_SERVER['REQUEST_METHOD'] === 'POST' && !empty($_POST['stop_production'])) { + $id = (int)$_POST['id']; + $reason = $_POST['reason'] ?? 'fine'; + $note = trim($_POST['note'] ?? ''); + try { + $sql = "SELECT start_time, id_status FROM productiondata WHERE id = :id"; + $stmt = $pdo->prepare($sql); + $stmt->execute(['id' => $id]); + $row = $stmt->fetch(); + $seconds = 0; + if ($row && $row['start_time'] && $row['id_status'] == $statusProduzioneId) { + $start = new DateTime($row['start_time'], new DateTimeZone('UTC')); + $now = new DateTime('now', new DateTimeZone('UTC')); + $seconds = $now->getTimestamp() - $start->getTimestamp(); + } + + // Stato di destinazione + $nextStatus = ($reason === 'problema') ? 8 : $statusQualita; // 8 = Problema in produzione + + $sql = "UPDATE productiondata + SET id_status = :status, + end_time = UTC_TIMESTAMP(), + note_operatore = :note + WHERE id = :id AND id_status IN ($statusProduzioneId, $statusPausaId)"; + $stmt = $pdo->prepare($sql); + $stmt->execute([ + 'status' => $nextStatus, + 'seconds' => $seconds, + 'note' => $note ?: null, + 'id' => $id, + 'produzione' => $statusProduzioneId, + 'pausa' => $statusPausaId + ]); + echo json_encode(['success' => true]); + } catch (Exception $e) { + echo json_encode(['success' => false, 'msg' => $e->getMessage()]); + } + exit; +} + +// --- SALVATAGGIO DATI FINE PRODUZIONE --- +if ($_SERVER['REQUEST_METHOD'] === 'POST' && !empty($_POST['save_final_data'])) { + $id = (int)$_POST['id']; + $kgprod = (float)$_POST['kgprod']; + $mtprod = (float)$_POST['mtprod']; + $scarto = (float)$_POST['scarto']; + $note = trim($_POST['note'] ?? ''); + $reason = $_POST['reason'] ?? 'fine'; + + try { + // Calcolo automatico del tempo totale in ore + $sql = "SELECT tempo_totale_produzione FROM productiondata WHERE id = :id"; + $stmt = $pdo->prepare($sql); + $stmt->execute(['id' => $id]); + $seconds = (int)$stmt->fetchColumn(); + $hours = round($seconds / 3600, 2); + + // Stato di destinazione + $nextStatus = ($reason === 'problema') ? 8 : $statusQualita; + + $sql = "UPDATE productiondata + SET kgprod = :kgprod, + mtprod = :mtprod, + scarto = :scarto, + note_operatore = :note, + hourprod = SEC_TO_TIME(:seconds), + id_status = :status, + end_time = COALESCE(end_time, UTC_TIMESTAMP()) + WHERE id = :id"; + $stmt = $pdo->prepare($sql); + $stmt->execute([ + 'kgprod' => $kgprod, + 'mtprod' => $mtprod, + 'scarto' => $scarto, + 'note' => $note, + 'seconds' => $seconds, + 'status' => $nextStatus, + 'id' => $id + ]); + + echo json_encode(['success' => true]); + } catch (Exception $e) { + echo json_encode(['success' => false, 'msg' => $e->getMessage()]); + } + exit; +} + +// --- AJAX PRINCIPALE: carica i record della data selezionata --- +if (!empty($_GET['ajax'])) { + + $lineRaw = $_GET['line'] ?? ''; + $lineArray = $lineRaw !== '' ? explode(',', $lineRaw) : []; + + // --- RECORD IN PRODUZIONE (2,7,8) + $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.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(); + $records = $stmt->fetchAll(); + + 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 '| ID | +Nome | +Descrizione | +Tipo | +Azioni | +
|---|---|---|---|---|
| = $row['id'] ?> | += htmlspecialchars($row['name']) ?> | += htmlspecialchars($row['description']) ?> | + ++ + Problema tecnico + + Pausa + + | + ++ + + + | +