getConnection(); function h($v) { return htmlspecialchars((string)$v, ENT_QUOTES, 'UTF-8'); } function formatDateIT($d) { if (!$d || $d === '0000-00-00') return '—'; return date('d/m/Y', strtotime($d)); } function formatDateTimeIT($d) { if (!$d || $d === '0000-00-00 00:00:00') return '—'; return date('d/m/Y H:i', strtotime($d)); } function getRevisionLabel($rev) { $rev = trim((string)$rev); return $rev !== '' ? $rev : '0'; } function getWorksheetLabel($num) { $num = (int)$num; return $num > 0 ? 'FL' . $num : '—'; } // AJAX HANDLERS if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['ajax']) && $_POST['ajax'] == '1') { header('Content-Type: application/json; charset=utf-8'); $action = $_POST['action'] ?? ''; try { if ($action === 'delete') { $id = (int)($_POST['id'] ?? 0); if ($id <= 0) { echo json_encode(['success' => false, 'message' => 'ID non valido']); exit; } $stmt = $pdo->prepare("DELETE FROM work_sheets WHERE id = ?"); $stmt->execute([$id]); echo json_encode(['success' => true]); exit; } if ($action === 'create_revision') { $id = (int)($_POST['id'] ?? 0); if ($id <= 0) { echo json_encode(['success' => false, 'message' => 'ID non valido']); exit; } $stmt = $pdo->prepare(" SELECT * FROM work_sheets WHERE id = ? LIMIT 1 "); $stmt->execute([$id]); $source = $stmt->fetch(PDO::FETCH_ASSOC); if (!$source) { echo json_encode(['success' => false, 'message' => 'Foglio non trovato']); exit; } if (($source['worksheet_status'] ?? 'active') !== 'active') { echo json_encode([ 'success' => false, 'message' => 'Questo foglio è già inattivo/revisionato e non può essere revisionato di nuovo' ]); exit; } $idmatrice = (int)$source['idmatrice']; if ($idmatrice <= 0) { echo json_encode(['success' => false, 'message' => 'ID matrice non valido']); exit; } $worksheetNumber = (int)($source['worksheet_number'] ?? 0); if ($worksheetNumber <= 0) { echo json_encode(['success' => false, 'message' => 'Numero foglio non valido o non valorizzato']); exit; } $pdo->beginTransaction(); // Trova la prossima revisione sulla stessa numerazione foglio $stmtMaxRev = $pdo->prepare(" SELECT revision_code FROM work_sheets WHERE worksheet_number = ? ORDER BY CASE WHEN revision_code IS NULL OR revision_code = '' THEN 0 WHEN revision_code REGEXP '^R[0-9]+$' THEN CAST(SUBSTRING(revision_code, 2) AS UNSIGNED) ELSE 0 END DESC, id DESC LIMIT 1 "); $stmtMaxRev->execute([$worksheetNumber]); $lastRevisionCode = $stmtMaxRev->fetchColumn(); $nextRevisionNumber = 1; if ($lastRevisionCode && preg_match('/^R(\d+)$/', $lastRevisionCode, $m)) { $nextRevisionNumber = ((int)$m[1]) + 1; } $newRevisionCode = 'R' . $nextRevisionNumber; // Rendi inattivo il foglio corrente $stmtDeactivate = $pdo->prepare(" UPDATE work_sheets SET worksheet_status = 'inactive' WHERE id = ? "); $stmtDeactivate->execute([$id]); // Crea clone del foglio mantenendo lo stesso worksheet_number $stmtInsert = $pdo->prepare(" INSERT INTO work_sheets ( worksheet_number, idmatrice, worksheet_date, customer_name, profile_type_code, revision_code, worksheet_status, marking, prod_control_measure_settings, control_frequency_cut, control_frequency_drawing, control_frequency_jig, control_mode_jig, requested_package_code, meters_per_package, meters_per_package_tolerance, meters_per_package_notes, box_type, packages_or_pieces_per_box, meters_per_box, pallet_type, boxes_or_packages_per_pallet, speed_expected_kg_h, speed_actual_kg_h, speed_expected_m_h, speed_actual_m_h, approved_by, notes ) VALUES ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? ) "); $stmtInsert->execute([ $worksheetNumber, $source['idmatrice'], $source['worksheet_date'], $source['customer_name'], $source['profile_type_code'], $newRevisionCode, 'active', $source['marking'], $source['prod_control_measure_settings'], $source['control_frequency_cut'], $source['control_frequency_drawing'], $source['control_frequency_jig'], $source['control_mode_jig'], $source['requested_package_code'], $source['meters_per_package'], $source['meters_per_package_tolerance'], $source['meters_per_package_notes'], $source['box_type'], $source['packages_or_pieces_per_box'], $source['meters_per_box'], $source['pallet_type'], $source['boxes_or_packages_per_pallet'], $source['speed_expected_kg_h'], $source['speed_actual_kg_h'], $source['speed_expected_m_h'], $source['speed_actual_m_h'], $source['approved_by'], $source['notes'] ]); $newWorksheetId = (int)$pdo->lastInsertId(); // Duplica le mescole collegate $stmtMixes = $pdo->prepare(" SELECT idmescola, mix_position, mix_weight_g_m, support_weight_g_m, required_density, required_hardness_shore_a, lubrication_type, lubrication_notes FROM work_sheet_mescole WHERE worksheet_id = ? ORDER BY mix_position ASC, id ASC "); $stmtMixes->execute([$id]); $mixRows = $stmtMixes->fetchAll(PDO::FETCH_ASSOC); if ($mixRows) { $stmtInsertMix = $pdo->prepare(" INSERT INTO work_sheet_mescole ( worksheet_id, idmescola, mix_position, mix_weight_g_m, support_weight_g_m, required_density, required_hardness_shore_a, lubrication_type, lubrication_notes ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) "); foreach ($mixRows as $mix) { $stmtInsertMix->execute([ $newWorksheetId, $mix['idmescola'], $mix['mix_position'], $mix['mix_weight_g_m'], $mix['support_weight_g_m'], $mix['required_density'], $mix['required_hardness_shore_a'], $mix['lubrication_type'], $mix['lubrication_notes'] ]); } } $pdo->commit(); echo json_encode([ 'success' => true, 'message' => 'Revisione creata correttamente', 'new_id' => $newWorksheetId, 'new_revision_code' => $newRevisionCode, 'worksheet_number_label' => 'FL' . $worksheetNumber ]); exit; } if ($action === 'deactivate') { $id = (int)($_POST['id'] ?? 0); if ($id <= 0) { echo json_encode(['success' => false, 'message' => 'ID non valido']); exit; } $stmt = $pdo->prepare(" UPDATE work_sheets SET worksheet_status = 'inactive' WHERE id = ? AND COALESCE(NULLIF(worksheet_status, ''), 'active') = 'active' "); $stmt->execute([$id]); if ($stmt->rowCount() === 0) { echo json_encode(['success' => false, 'message' => 'Foglio non trovato o già inattivo']); exit; } echo json_encode(['success' => true, 'message' => 'Foglio disattivato']); exit; } if ($action === 'reactivate') { $id = (int)($_POST['id'] ?? 0); if ($id <= 0) { echo json_encode(['success' => false, 'message' => 'ID non valido']); exit; } $stmt = $pdo->prepare("SELECT id, worksheet_number, worksheet_status FROM work_sheets WHERE id = ? LIMIT 1"); $stmt->execute([$id]); $ws = $stmt->fetch(PDO::FETCH_ASSOC); if (!$ws) { echo json_encode(['success' => false, 'message' => 'Foglio non trovato']); exit; } if (($ws['worksheet_status'] ?: 'active') === 'active') { echo json_encode(['success' => false, 'message' => 'Il foglio è già attivo']); exit; } // Non riattivare se esiste già un'altra revisione attiva dello stesso FL $wsNumber = (int)$ws['worksheet_number']; if ($wsNumber > 0) { $stmtChk = $pdo->prepare(" SELECT COALESCE(NULLIF(revision_code, ''), '0') FROM work_sheets WHERE worksheet_number = ? AND id <> ? AND COALESCE(NULLIF(worksheet_status, ''), 'active') = 'active' LIMIT 1 "); $stmtChk->execute([$wsNumber, $id]); $activeRev = $stmtChk->fetchColumn(); if ($activeRev !== false) { echo json_encode([ 'success' => false, 'message' => 'Esiste già una revisione attiva di FL' . $wsNumber . ' (rev. ' . $activeRev . '). Disattivala prima di riattivare questa.' ]); exit; } } $stmt = $pdo->prepare("UPDATE work_sheets SET worksheet_status = 'active' WHERE id = ?"); $stmt->execute([$id]); echo json_encode(['success' => true, 'message' => 'Foglio riattivato']); exit; } echo json_encode(['success' => false, 'message' => 'Azione sconosciuta']); exit; } catch (Exception $e) { if ($pdo->inTransaction()) { $pdo->rollBack(); } echo json_encode(['success' => false, 'message' => $e->getMessage()]); exit; } } // Worksheets list + row count $worksheets = $pdo->query(" SELECT ws.id, ws.worksheet_number, ws.worksheet_date, ws.customer_name, ws.profile_type_code, ws.revision_code, ws.worksheet_status, ws.approved_by, ws.created_at, ws.updated_at, m.nome AS matrice_nome, m.cliente AS matrice_cliente, ( SELECT COUNT(*) FROM work_sheet_mescole wsm WHERE wsm.worksheet_id = ws.id ) AS mixes_count, ( SELECT COUNT(*) FROM work_sheets ws2 WHERE ws.worksheet_number > 0 AND ws2.worksheet_number = ws.worksheet_number AND ws2.id > ws.id ) AS newer_count, ( SELECT COUNT(*) FROM work_sheets ws3 WHERE ws.worksheet_number > 0 AND ws3.worksheet_number = ws.worksheet_number AND ws3.id <> ws.id AND COALESCE(NULLIF(ws3.worksheet_status, ''), 'active') = 'active' ) AS active_siblings FROM work_sheets ws LEFT JOIN matrice m ON ws.idmatrice = m.id ORDER BY ws.worksheet_number DESC, ws.id DESC ")->fetchAll(PDO::FETCH_ASSOC); ?> Fogli di Lavoro
Fogli di Lavoro
Storico
0; $canReactivate = !$isActive && (int)($ws['active_siblings'] ?? 0) === 0; $wsFullName = ($ws['matrice_nome'] ?? 'Foglio') . ' ' . $worksheetLabel . ' rev. ' . $revisionLabel; ?>
Foglio Rev Data Matrice/Profilo Cliente Codice Profilo Stato Mescole Visto Creato Azioni
Attivo Revisionato Disattivato
>