false, 'error' => 'Acceso no autorizado.']); exit; } $pdo = db(); function cc_column_exists(PDO $pdo, string $column): bool { $stmt = $pdo->prepare('SHOW COLUMNS FROM pedidos LIKE ?'); $stmt->execute([$column]); return (bool) $stmt->fetch(); } function cc_ensure_contraentrega_verificacion_columns(PDO $pdo): void { $columns = [ 'contraentrega_verificacion_imagen_path' => 'VARCHAR(500) NULL', 'contraentrega_verificacion_tracking' => 'VARCHAR(255) NULL', 'contraentrega_verificacion_user_id' => 'INT NULL', 'contraentrega_verificacion_created_at' => 'TIMESTAMP NULL DEFAULT NULL', ]; foreach ($columns as $col => $def) { if (!cc_column_exists($pdo, $col)) { // DDL: safe because we only use constant column names/definitions. $pdo->exec('ALTER TABLE pedidos ADD COLUMN ' . $col . ' ' . $def); } } } $user_id = (int) ($_SESSION['user_id'] ?? 0); $user_role = (string) ($_SESSION['user_role'] ?? 'Asesor'); $pedido_id = (int) (($_POST['pedido_id'] ?? '') !== '' ? $_POST['pedido_id'] : 0); $tracking_verificacion = trim((string) ($_POST['tracking_verificacion'] ?? '')); if ($pedido_id <= 0) { http_response_code(400); echo json_encode(['success' => false, 'error' => 'pedido_id es obligatorio.']); exit; } if ($tracking_verificacion === '') { http_response_code(400); echo json_encode(['success' => false, 'error' => 'tracking_verificacion es obligatorio.']); exit; } // Permission check $stmtPedido = $pdo->prepare('SELECT id, asesor_id FROM pedidos WHERE id = ? LIMIT 1'); $stmtPedido->execute([$pedido_id]); $pedido = $stmtPedido->fetch(PDO::FETCH_ASSOC); if (!$pedido) { http_response_code(404); echo json_encode(['success' => false, 'error' => 'Pedido no encontrado.']); exit; } if ($user_role === 'Asesor' && (int) ($pedido['asesor_id'] ?? 0) !== $user_id) { http_response_code(403); echo json_encode(['success' => false, 'error' => 'No autorizado para gestionar este pedido.']); exit; } if (!isset($_FILES['imagen']) || !is_array($_FILES['imagen'])) { http_response_code(400); echo json_encode(['success' => false, 'error' => 'imagen es obligatoria.']); exit; } $imagen = $_FILES['imagen']; if (($imagen['error'] ?? UPLOAD_ERR_NO_FILE) !== UPLOAD_ERR_OK) { http_response_code(400); echo json_encode(['success' => false, 'error' => 'Error al subir la imagen.']); exit; } $maxSize = 8 * 1024 * 1024; // 8MB if (!isset($imagen['size']) || (int)$imagen['size'] <= 0 || (int)$imagen['size'] > $maxSize) { http_response_code(400); echo json_encode(['success' => false, 'error' => 'La imagen excede el tamaño máximo permitido (8MB).']); exit; } $tmpName = (string) ($imagen['tmp_name'] ?? ''); if ($tmpName === '' || !file_exists($tmpName)) { http_response_code(400); echo json_encode(['success' => false, 'error' => 'Temp file inválido.']); exit; } $imgInfo = @getimagesize($tmpName); if ($imgInfo === false || empty($imgInfo['mime'])) { http_response_code(400); echo json_encode(['success' => false, 'error' => 'El archivo no parece ser una imagen válida.']); exit; } $mime = (string) $imgInfo['mime']; $allowed = [ 'image/jpeg' => 'jpg', 'image/png' => 'png', 'image/webp' => 'webp', ]; if (!isset($allowed[$mime])) { http_response_code(400); echo json_encode(['success' => false, 'error' => 'Formato no permitido. Use JPG, PNG o WEBP.']); exit; } $ext = $allowed[$mime]; $uploadDir = __DIR__ . '/assets/uploads/contraentrega_verificaciones'; if (!is_dir($uploadDir)) { mkdir($uploadDir, 0775, true); } $filename = sprintf( 'contraentrega_verificacion_%d_%d_%d_%s.%s', $pedido_id, $user_id, time(), bin2hex(random_bytes(4)), $ext ); $targetPath = $uploadDir . '/' . $filename; if (!move_uploaded_file($tmpName, $targetPath)) { http_response_code(500); echo json_encode(['success' => false, 'error' => 'No se pudo guardar la imagen en el servidor.']); exit; } $relativePath = 'assets/uploads/contraentrega_verificaciones/' . $filename; try { cc_ensure_contraentrega_verificacion_columns($pdo); $stmt = $pdo->prepare('UPDATE pedidos SET contraentrega_verificacion_imagen_path = ?, contraentrega_verificacion_tracking = ?, contraentrega_verificacion_user_id = ?, contraentrega_verificacion_created_at = NOW() WHERE id = ?'); $stmt->execute([$relativePath, $tracking_verificacion, $user_id, $pedido_id]); if ($stmt->rowCount() <= 0) { // Still treat as success because UPDATE might not change values echo json_encode(['success' => true, 'info' => 'La verificación se guardó, pero no hubo cambios.']); exit; } echo json_encode(['success' => true, 'imagen' => $relativePath, 'tracking_verificacion' => $tracking_verificacion]); } catch (Throwable $e) { error_log('save_contraentrega_verificacion.php: ' . $e->getMessage()); http_response_code(500); $msg = $e->getMessage(); if (is_string($msg) && strlen($msg) > 300) { $msg = substr($msg, 0, 300) . '...'; } echo json_encode(['success' => false, 'error' => 'Error al guardar la verificación. ' . $msg]); }