getConnection(); $worksheet_id = isset($_GET['id']) && is_numeric($_GET['id']) ? (int)$_GET['id'] : 0; // AJAX HANDLERS if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['ajax']) && $_POST['ajax'] == '1') { // Ensure clean JSON output while (ob_get_level()) { ob_end_clean(); } header('Content-Type: application/json; charset=utf-8'); $action = $_POST['action'] ?? ''; try { // Save header (insert/update) if ($action === 'save_header') { $idmatrice = (int)($_POST['idmatrice'] ?? 0); if ($idmatrice <= 0) { echo json_encode(['success' => false, 'message' => 'Seleziona una matrice/profilo']); exit; } $id = (int)($_POST['id'] ?? 0); $worksheet_date = $_POST['worksheet_date'] !== '' ? $_POST['worksheet_date'] : null; $customer_name = trim($_POST['customer_name'] ?? ''); $profile_code = trim($_POST['profile_type_code'] ?? ''); $marking = ($_POST['marking'] ?? '') !== '' ? $_POST['marking'] : null; $prod_control = trim($_POST['prod_control_measure_settings'] ?? ''); $freq_cut = trim($_POST['control_frequency_cut'] ?? ''); $freq_draw = trim($_POST['control_frequency_drawing'] ?? ''); $freq_jig = trim($_POST['control_frequency_jig'] ?? ''); $mode_jig = trim($_POST['control_mode_jig'] ?? ''); // Package data moved to worksheet header $requested_package_code = trim($_POST['requested_package_code'] ?? ''); $meters_per_package = $_POST['meters_per_package'] !== '' ? (int)$_POST['meters_per_package'] : null; $meters_per_package_tolerance = trim($_POST['meters_per_package_tolerance'] ?? ''); $meters_per_package_notes = trim($_POST['meters_per_package_notes'] ?? ''); $box_type = trim($_POST['box_type'] ?? ''); $pkg_box = $_POST['packages_or_pieces_per_box'] !== '' ? (int)$_POST['packages_or_pieces_per_box'] : null; $m_box = $_POST['meters_per_box'] !== '' ? (int)$_POST['meters_per_box'] : null; $pallet_type = trim($_POST['pallet_type'] ?? ''); $per_pallet = $_POST['boxes_or_packages_per_pallet'] !== '' ? (int)$_POST['boxes_or_packages_per_pallet'] : null; $sp_exp_kg = $_POST['speed_expected_kg_h'] !== '' ? (float)$_POST['speed_expected_kg_h'] : null; $sp_act_kg = $_POST['speed_actual_kg_h'] !== '' ? (float)$_POST['speed_actual_kg_h'] : null; $sp_exp_m = $_POST['speed_expected_m_h'] !== '' ? (float)$_POST['speed_expected_m_h'] : null; $sp_act_m = $_POST['speed_actual_m_h'] !== '' ? (float)$_POST['speed_actual_m_h'] : null; $approved_by = trim($_POST['approved_by'] ?? ''); $notes = trim($_POST['notes'] ?? ''); $worksheet_number = null; if ($id > 0) { $stmt = $pdo->prepare(" UPDATE work_sheets SET idmatrice = ?, worksheet_date = ?, customer_name = ?, profile_type_code = ?, 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 = ? WHERE id = ? "); $stmt->execute([ $idmatrice, $worksheet_date, $customer_name !== '' ? $customer_name : null, $profile_code !== '' ? $profile_code : null, $marking, $prod_control !== '' ? $prod_control : null, $freq_cut !== '' ? $freq_cut : null, $freq_draw !== '' ? $freq_draw : null, $freq_jig !== '' ? $freq_jig : null, $mode_jig !== '' ? $mode_jig : null, $requested_package_code !== '' ? $requested_package_code : null, $meters_per_package, $meters_per_package_tolerance !== '' ? $meters_per_package_tolerance : null, $meters_per_package_notes !== '' ? $meters_per_package_notes : null, $box_type !== '' ? $box_type : null, $pkg_box, $m_box, $pallet_type !== '' ? $pallet_type : null, $per_pallet, $sp_exp_kg, $sp_act_kg, $sp_exp_m, $sp_act_m, $approved_by !== '' ? $approved_by : null, $notes !== '' ? $notes : null, $id ]); echo json_encode(['success' => true, 'id' => $id]); exit; } $pdo->beginTransaction(); $stmtNum = $pdo->query(" SELECT IFNULL(MAX(worksheet_number), 0) + 1 AS next_number FROM work_sheets "); $worksheet_number = (int)$stmtNum->fetchColumn(); if ($worksheet_number <= 0) { $worksheet_number = 1; } $stmt = $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 ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? ) "); $stmt->execute([ $worksheet_number, $idmatrice, $worksheet_date, $customer_name !== '' ? $customer_name : null, $profile_code !== '' ? $profile_code : null, null, // revision_code = vuoto => revisione 0 'active', // worksheet_status $marking, $prod_control !== '' ? $prod_control : null, $freq_cut !== '' ? $freq_cut : null, $freq_draw !== '' ? $freq_draw : null, $freq_jig !== '' ? $freq_jig : null, $mode_jig !== '' ? $mode_jig : null, $requested_package_code !== '' ? $requested_package_code : null, $meters_per_package, $meters_per_package_tolerance !== '' ? $meters_per_package_tolerance : null, $meters_per_package_notes !== '' ? $meters_per_package_notes : null, $box_type !== '' ? $box_type : null, $pkg_box, $m_box, $pallet_type !== '' ? $pallet_type : null, $per_pallet, $sp_exp_kg, $sp_act_kg, $sp_exp_m, $sp_act_m, $approved_by !== '' ? $approved_by : null, $notes !== '' ? $notes : null ]); $newId = (int)$pdo->lastInsertId(); $pdo->commit(); echo json_encode([ 'success' => true, 'id' => $newId, 'worksheet_number' => $worksheet_number, 'worksheet_number_label' => worksheet_number_label($worksheet_number) ]); exit; } // Add or edit mix row if ($action === 'save_mix_row') { $worksheet_id = (int)($_POST['worksheet_id'] ?? 0); if ($worksheet_id <= 0) { echo json_encode(['success' => false, 'message' => 'Salva prima il foglio (testata)']); exit; } $row_id = (int)($_POST['row_id'] ?? 0); $idmescola = (int)($_POST['idmescola'] ?? 0); $pos = 0; // auto-assign if ($idmescola <= 0) { echo json_encode(['success' => false, 'message' => 'Seleziona una mescola']); exit; } if ($pos <= 0) $pos = 1; $mix_weight = $_POST['mix_weight_g_m'] !== '' ? (float)$_POST['mix_weight_g_m'] : null; $density = trim($_POST['required_density'] ?? ''); $hardness = trim($_POST['required_hardness_shore_a'] ?? ''); $lub_type = ($_POST['lubrication_type'] ?? '') !== '' ? $_POST['lubrication_type'] : null; $lub_note = trim($_POST['lubrication_notes'] ?? ''); $pdo->beginTransaction(); if ($row_id > 0) { $stmt = $pdo->prepare(" UPDATE work_sheet_mescole SET idmescola = ?, mix_weight_g_m = ?, required_density = ?, required_hardness_shore_a = ?, lubrication_type = ?, lubrication_notes = ? WHERE id = ? AND worksheet_id = ? "); $stmt->execute([ $idmescola, $mix_weight, $density !== '' ? $density : null, $hardness !== '' ? $hardness : null, $lub_type, $lub_note !== '' ? $lub_note : null, $row_id, $worksheet_id ]); $pdo->commit(); echo json_encode(['success' => true]); exit; } $stmtPos = $pdo->prepare(" SELECT IFNULL(MAX(mix_position), 0) + 1 FROM work_sheet_mescole WHERE worksheet_id = ? FOR UPDATE "); $stmtPos->execute([$worksheet_id]); $pos = (int)$stmtPos->fetchColumn(); if ($pos <= 0) $pos = 1; $stmt = $pdo->prepare(" INSERT INTO work_sheet_mescole ( worksheet_id, idmescola, mix_position, mix_weight_g_m, required_density, required_hardness_shore_a, lubrication_type, lubrication_notes ) VALUES (?, ?, ?, ?, ?, ?, ?, ?) "); $stmt->execute([ $worksheet_id, $idmescola, $pos, $mix_weight, $density !== '' ? $density : null, $hardness !== '' ? $hardness : null, $lub_type, $lub_note !== '' ? $lub_note : null ]); $pdo->commit(); echo json_encode(['success' => true]); exit; } // Delete mix row if ($action === 'delete_mix_row') { $row_id = (int)($_POST['row_id'] ?? 0); if ($row_id <= 0) { echo json_encode(['success' => false, 'message' => 'ID riga non valido']); exit; } $stmt = $pdo->prepare("DELETE FROM work_sheet_mescole WHERE id = ?"); $stmt->execute([$row_id]); echo json_encode(['success' => true]); 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; } } // Load matrices dropdown $matrici = $pdo->query(" SELECT id, nome, cliente FROM matrice ORDER BY nome ASC ")->fetchAll(PDO::FETCH_ASSOC); // Load generic worksheet lookup options $lookup = []; $lookupDefault = []; $stmt = $pdo->prepare(" SELECT category, value, label, is_default FROM ws_lookup_options WHERE is_active = 1 ORDER BY category ASC, sort_order ASC, label ASC "); $stmt->execute(); foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $r) { $lookup[$r['category']][] = $r; if ((int)$r['is_default'] === 1 && !isset($lookupDefault[$r['category']])) { $lookupDefault[$r['category']] = $r['value']; } } // Load packaging items from dedicated table $packagingLookup = [ 'PACKAGING_TYPE' => [], 'BOX' => [], 'PALLET' => [] ]; $stmt = $pdo->prepare(" SELECT category, item_name, item_code FROM packaging_items WHERE is_active = 1 AND category IN ('PACKAGING_TYPE', 'BOX', 'PALLET') ORDER BY category ASC, item_name ASC "); $stmt->execute(); foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $r) { $label = $r['item_name']; if (!empty($r['item_code'])) { $label .= ' — ' . $r['item_code']; } $packagingLookup[$r['category']][] = [ 'value' => $r['item_code'], 'label' => $label ]; } // Load mescole dropdown for modal $mescole = $pdo->query(" SELECT id, nome, nomeuscita FROM mescole ORDER BY nome ASC ")->fetchAll(PDO::FETCH_ASSOC); // Load worksheet (edit) $worksheet = null; $mixRows = []; if ($worksheet_id > 0) { $stmt = $pdo->prepare(" SELECT ws.*, m.nome AS matrice_nome FROM work_sheets ws LEFT JOIN matrice m ON ws.idmatrice = m.id WHERE ws.id = ? "); $stmt->execute([$worksheet_id]); $worksheet = $stmt->fetch(PDO::FETCH_ASSOC); if ($worksheet) { $stmt = $pdo->prepare(" SELECT wsm.*, me.nome AS mescola_nome, me.nomeuscita AS mescola_uscita FROM work_sheet_mescole wsm LEFT JOIN mescole me ON me.id = wsm.idmescola WHERE wsm.worksheet_id = ? ORDER BY wsm.mix_position ASC, wsm.id ASC "); $stmt->execute([$worksheet_id]); $mixRows = $stmt->fetchAll(PDO::FETCH_ASSOC); } else { $worksheet_id = 0; } } // Helpers function h($v) { return htmlspecialchars((string)$v, ENT_QUOTES); } function worksheet_number_label($n) { $n = (int)$n; return $n > 0 ? 'FL' . $n : 'Non assegnato'; } function ws_options($rows, $selectedValue, $defaultValue = '') { $selectedValue = (string)$selectedValue; if ($selectedValue === '' && $defaultValue !== '') { $selectedValue = (string)$defaultValue; } $html = ''; if (!$rows) return $html; foreach ($rows as $r) { $val = h($r['value']); $lab = h($r['label']); $sel = ((string)$r['value'] === $selectedValue) ? ' selected' : ''; $html .= ""; } return $html; } function packaging_options($rows, $selectedValue = '') { $selectedValue = (string)$selectedValue; $html = ''; if (!$rows) return $html; foreach ($rows as $r) { $val = h($r['value']); $lab = h($r['label']); $sel = ((string)$r['value'] === $selectedValue) ? ' selected' : ''; $html .= ""; } return $html; } $isEdit = ($worksheet_id > 0); ?> <?= $isEdit ? 'Modifica Foglio di Lavoro' : 'Nuovo Foglio di Lavoro' ?>

Pagina pensata per uso operativo in produzione: prima salva la testata, poi inserisci le mescole

Stato foglio
Foglio / Revisione
Mescole inserite
Passaggio operativo
0 ? 'Puoi aggiungere mescole' : 'Salva prima la testata' ?>
1. Dati principali del foglio

Campi iniziali per identificare il lavoro

Obbligatorio: matrice / profilo
Seleziona il profilo da produrre
Compila solo se vuoi specificare un nome cliente manuale
2. Controlli di produzione

Istruzioni e frequenze di controllo per l’operatore

Sezione operativa
3. Imballo e confezionamento

Dati per confezione, scatola e bancale

Packaging
Compila prima la confezione, poi eventuali dettagli di scatola e bancale
4. Velocità di produzione

Confronto tra velocità prevista ed effettiva

Prestazioni linea
5. Note finali

Annotazioni operative o indicazioni aggiuntive

Facoltativo
Flusso consigliato
1. Compila la testata → 2. Salva → 3. Aggiungi una o più mescole
6. Mescole associate al foglio

Inserisci una o più righe mescola dopo il salvataggio della testata

righe
Elenco mescole
Puoi modificare o eliminare ogni riga direttamente dalla tabella
Pos Mescola Peso (g/m) Densità Durezza Lubr. Azioni