'', 'in_progress' => '', 'completed' => '']); if (!array_key_exists($status, $validStatuses)) { mnt_json_fail('Stato intervento non valido.'); } $validResults = mnt_lookup($pdo, 'maint_result', []); if ($result !== '' && $validResults && !array_key_exists($result, $validResults)) { mnt_json_fail('Esito intervento non valido.'); } // Existing row: maintenance is taken from the record, not from the client if ($id > 0) { $stmt = $pdo->prepare("SELECT * FROM maint_interventions WHERE id = ?"); $stmt->execute([$id]); $existing = $stmt->fetch(PDO::FETCH_ASSOC); if (!$existing) { mnt_json_fail('Intervento non trovato.'); } $maintenanceId = (int)$existing['maintenance_id']; $equipmentId = (int)$existing['equipment_id']; $signaturePath = $existing['signature_path']; } else { $stmt = $pdo->prepare("SELECT equipment_id FROM maint_maintenances WHERE id = ?"); $stmt->execute([$maintenanceId]); $equipmentId = (int)$stmt->fetchColumn(); if (!$equipmentId) { mnt_json_fail('Manutenzione non trovata.'); } $signaturePath = null; } // Signature handling if ($clearSignature && $signaturePath) { mnt_delete_stored_file((string)$signaturePath); $signaturePath = null; } if ($signatureData !== '' && preg_match('#^data:image/png;base64,#', $signatureData)) { $binary = base64_decode(substr($signatureData, strlen('data:image/png;base64,')), true); if ($binary === false || strlen($binary) > 2 * 1024 * 1024) { mnt_json_fail('Firma non valida.'); } $uploadDir = __DIR__ . '/../attachments/'; if (!is_dir($uploadDir) && !mkdir($uploadDir, 0755, true) && !is_dir($uploadDir)) { mnt_json_fail('Cartella allegati non scrivibile.'); } $newSignature = uniqid('sig_', true) . '.png'; $newSignature = preg_replace('/[^A-Za-z0-9._-]/', '_', $newSignature); if (file_put_contents($uploadDir . $newSignature, $binary) === false) { mnt_json_fail('Impossibile salvare la firma.'); } if ($signaturePath) { mnt_delete_stored_file((string)$signaturePath); } $signaturePath = $newSignature; } $values = [ 'performed_at' => $performedAt, 'status' => $status, 'result' => $result ?: null, 'notes' => $notes ?: null, 'materials' => $materials ?: null, 'operator_employee_id' => $operatorId ?: null, 'operator_name' => $operatorName ?: null, 'supplier_id' => $supplierId ?: null, 'signature_path' => $signaturePath, ]; if ($id > 0) { $assignments = []; foreach (array_keys($values) as $column) { $assignments[] = "$column = :$column"; } $stmt = $pdo->prepare("UPDATE maint_interventions SET " . implode(', ', $assignments) . " WHERE id = :id"); $stmt->execute($values + ['id' => $id]); $interventionId = $id; $action = 'intervention_updated'; } else { $values['maintenance_id'] = $maintenanceId; $values['equipment_id'] = $equipmentId; $values['created_by'] = $currentUserId; $columns = array_keys($values); $placeholders = array_map(fn($column) => ':' . $column, $columns); $stmt = $pdo->prepare( "INSERT INTO maint_interventions (" . implode(', ', $columns) . ") VALUES (" . implode(', ', $placeholders) . ")" ); $stmt->execute($values); $interventionId = (int)$pdo->lastInsertId(); $action = 'intervention_created'; } // Only completed interventions move the next due date; this call handles it mnt_recalc_maintenance($pdo, $maintenanceId); mnt_log($pdo, $action, $equipmentId, $maintenanceId, $interventionId, $currentUserId, $values); $stmt = $pdo->prepare("SELECT last_done_date, next_due_date FROM maint_maintenances WHERE id = ?"); $stmt->execute([$maintenanceId]); $schedule = $stmt->fetch(PDO::FETCH_ASSOC) ?: []; mnt_json_ok(['id' => $interventionId, 'schedule' => $schedule]); } catch (Throwable $e) { mnt_json_fail('Errore: ' . $e->getMessage()); }