1ra Versión

This commit is contained in:
MarcosFlorSalcedo
2026-07-14 18:24:27 -03:00
commit 8ec55e40fc
86 changed files with 15839 additions and 0 deletions
+43
View File
@@ -0,0 +1,43 @@
<?php
include 'conexion.php';
// Leer el JSON enviado por JS
$json = file_get_contents('php://input');
$data = json_decode($json, true);
if (!$data) {
die("No se recibieron datos.");
}
$tipo = $data['tipo'];
$precio = $data['precio'];
$duracion = $data['duracion'];
$cantidad = $data['cantidad'];
$res_cupon = $data['reservas_cupon'];
$descuento = floatval(str_replace(',', '.', (string)($data['descuento'] ?? 0)));
if ($descuento > 1) {
$descuento = $descuento / 100;
}
$descuento = round($descuento, 4);
$faltas = $data['faltas'];
$duracion_cupon = $data['duracion_cupon'];
// Evitar inyección SQL básica
$tipo = mysqli_real_escape_string($conexion, $tipo);
$sql = "UPDATE canchas SET
Precio = '$precio',
Duracion = '$duracion',
Cant_Canchas = '$cantidad',
Cant_Reservas_Cupon = '$res_cupon',
Descuento_Cupon = '$descuento',
Cant_Faltas = '$faltas',
Duracion_Cupon = '$duracion_cupon'
WHERE Tipo = '$tipo'";
if (mysqli_query($conexion, $sql)) {
echo "Configuración de " . $tipo . " actualizada correctamente.";
} else {
echo "Error al actualizar: " . mysqli_error($conexion);
}
?>
+32
View File
@@ -0,0 +1,32 @@
<?php
include 'conexion.php';
// Leer el JSON enviado
$json = file_get_contents('php://input');
$data = json_decode($json, true);
if (!$data || !isset($data['id_reserva']) || !isset($data['estado'])) {
echo json_encode(['success' => false, 'error' => 'Datos incompletos']);
exit;
}
$id_reserva = intval($data['id_reserva']);
$estado = intval($data['estado']);
// Validar que el estado sea 0, 1 o 2
if (!in_array($estado, [0, 1, 2])) {
echo json_encode(['success' => false, 'error' => 'Estado inválido']);
exit;
}
// Actualizar la reserva
$sql = "UPDATE reservas SET Estado = $estado WHERE ID_Reserva = $id_reserva";
if (mysqli_query($conexion, $sql)) {
echo json_encode(['success' => true, 'message' => 'Estado actualizado correctamente']);
} else {
echo json_encode(['success' => false, 'error' => mysqli_error($conexion)]);
}
mysqli_close($conexion);
?>
+106
View File
@@ -0,0 +1,106 @@
<?php
require_once 'conexion.php';
header('Content-Type: application/json');
try {
$data = json_decode(file_get_contents('php://input'), true);
// Validar datos
if (!isset($data['gastos']) || empty($data['gastos'])) {
throw new Exception("No hay datos de gastos para guardar");
}
$gastos = $data['gastos'];
$fecha_hoy = date('Y-m-d');
// Buscar el registro actual (donde Periodo_Hasta IS NULL)
$sql_get_actual = "SELECT ID_Gasto FROM gastos WHERE Periodo_Hasta IS NULL ORDER BY Periodo_Desde DESC LIMIT 1";
$result_actual = $conexion->query($sql_get_actual);
if ($result_actual && $result_actual->num_rows > 0) {
$row_actual = $result_actual->fetch_assoc();
$id_gasto_actual = $row_actual['ID_Gasto'];
// Actualizar el Periodo_Hasta del registro actual con la fecha actual
$sql_update = "UPDATE gastos SET Periodo_Hasta = ? WHERE ID_Gasto = ?";
$stmt_update = $conexion->prepare($sql_update);
if (!$stmt_update) {
throw new Exception("Error preparando UPDATE: " . $conexion->error);
}
$stmt_update->bind_param('si', $fecha_hoy, $id_gasto_actual);
if (!$stmt_update->execute()) {
throw new Exception("Error actualizando período anterior: " . $stmt_update->error);
}
$stmt_update->close();
// Obtener todos los valores del registro que acaba de cerrarse
$sql_get_values = "SELECT * FROM gastos WHERE ID_Gasto = ?";
$stmt_get_values = $conexion->prepare($sql_get_values);
$stmt_get_values->bind_param('i', $id_gasto_actual);
$stmt_get_values->execute();
$result_values = $stmt_get_values->get_result();
$valores_anteriores = $result_values->fetch_assoc();
$stmt_get_values->close();
} else {
$valores_anteriores = null;
}
// Construir INSERT dinámico
$columnas = ['Periodo_Desde', 'Periodo_Hasta'];
$valores = [$fecha_hoy, null];
$placeholders = ['?', '?'];
$tipos = 'ss';
// Agregar columnas de gastos del request
foreach ($gastos as $col => $val) {
$columnas[] = $col;
$valores[] = floatval($val);
$placeholders[] = '?';
$tipos .= 'd';
}
// Agregar columnas restantes del registro anterior (si existen)
if (!empty($valores_anteriores)) {
foreach ($valores_anteriores as $col => $val) {
if (!in_array($col, ['ID_Gasto', 'Periodo_Desde', 'Periodo_Hasta']) && !isset($gastos[$col])) {
$columnas[] = $col;
$valores[] = floatval($val);
$placeholders[] = '?';
$tipos .= 'd';
}
}
}
$sql_insert = "INSERT INTO gastos (" . implode(', ', $columnas) . ") VALUES (" . implode(', ', $placeholders) . ")";
$stmt_insert = $conexion->prepare($sql_insert);
if (!$stmt_insert) {
throw new Exception("Error preparando INSERT: " . $conexion->error);
}
$stmt_insert->bind_param($tipos, ...$valores);
if (!$stmt_insert->execute()) {
throw new Exception("Error insertando registro: " . $stmt_insert->error);
}
$nuevo_id = $stmt_insert->insert_id;
$stmt_insert->close();
echo json_encode([
'success' => true,
'message' => 'Gastos guardados correctamente',
'id_gasto' => $nuevo_id
]);
} catch (Exception $e) {
echo json_encode([
'success' => false,
'message' => $e->getMessage()
]);
}
?>
+48
View File
@@ -0,0 +1,48 @@
<?php
include 'conexion.php';
header('Content-Type: application/json; charset=UTF-8');
$json = trim(file_get_contents('php://input'));
if ($json === '') {
echo json_encode(['success' => false, 'error' => 'Cuerpo vacío o no se envió JSON']);
exit;
}
$data = json_decode($json, true);
if (!is_array($data) || json_last_error() !== JSON_ERROR_NONE) {
$rawPreview = substr($json, 0, 200);
echo json_encode([
'success' => false,
'error' => 'JSON inválido en la solicitud',
'detalle' => json_last_error_msg(),
'raw' => $rawPreview,
'raw_hex' => bin2hex(substr($json, 0, 50))
]);
exit;
}
if (!isset($data['id_reserva']) || !isset($data['fecha_hora'])) {
echo json_encode(['success' => false, 'error' => 'Datos incompletos']);
exit;
}
$id_reserva = intval($data['id_reserva']);
$fecha_hora = $conexion->real_escape_string($data['fecha_hora']);
// Validación básica de formato YYYY-MM-DD HH:MM:SS
if (!preg_match('/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/', $fecha_hora)) {
echo json_encode(['success' => false, 'error' => 'Formato de fecha_hora inválido. Use YYYY-MM-DD HH:MM:SS']);
exit;
}
$sql = "UPDATE reservas SET Fecha_Hora = '$fecha_hora' WHERE ID_Reserva = $id_reserva";
if (mysqli_query($conexion, $sql)) {
echo json_encode(['success' => true, 'message' => 'Horario actualizado correctamente']);
} else {
echo json_encode(['success' => false, 'error' => mysqli_error($conexion)]);
}
mysqli_close($conexion);
?>
+18
View File
@@ -0,0 +1,18 @@
<?php
include 'conexion.php';
$datos = json_decode(file_get_contents("php://input"), true);
$error = false;
foreach ($datos as $h) {
$dia = $h['dia'];
$ape = $h['ape'];
$cie = $h['cie'];
$sql = "UPDATE horarios SET Hora_Apertura = '$ape', Hora_Cierre = '$cie' WHERE Dia = '$dia'";
if (!mysqli_query($conexion, $sql)) {
$error = true;
}
}
echo $error ? "Error al actualizar algunos horarios" : "Horarios actualizados correctamente";
?>
+136
View File
@@ -0,0 +1,136 @@
<?php
header('Content-Type: application/json');
mysqli_report(MYSQLI_REPORT_OFF);
$data = json_decode(file_get_contents('php://input'), true);
require_once 'conexion.php';
if ($conexion->connect_error) {
echo json_encode(['success' => false, 'error' => 'No hay conexión con la base de datos.']);
exit;
}
if (!is_array($data) || !isset($data['id'])) {
echo json_encode(['success' => false, 'error' => 'Faltan datos requeridos.']);
exit;
}
$idOrden = intval($data['id']);
$estado = isset($data['estado']) ? intval($data['estado']) : (isset($data['aprobada']) ? intval($data['aprobada']) : 0);
if (!in_array($estado, [0, 1, 2, 3], true)) {
echo json_encode(['success' => false, 'error' => 'Estado no válido.']);
exit;
}
function tableHasColumn($conexion, $table, $column)
{
$stmt = $conexion->prepare(
"SELECT COUNT(*) AS count FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ? AND COLUMN_NAME = ?"
);
if (!$stmt) {
return false;
}
$stmt->bind_param('ss', $table, $column);
$stmt->execute();
$result = $stmt->get_result();
$row = $result ? $result->fetch_assoc() : null;
$stmt->close();
return $row && intval($row['count']) > 0;
}
$hasEstado = tableHasColumn($conexion, 'ordenes_compra', 'Estado');
if (!$hasEstado) {
$alterQuery = "ALTER TABLE ordenes_compra ADD COLUMN Estado TINYINT(1) DEFAULT 0";
if (!$conexion->query($alterQuery)) {
echo json_encode(['success' => false, 'error' => 'No se pudo corregir la estructura de la tabla: ' . $conexion->error]);
exit;
}
$hasEstado = true;
}
$hasAprobada = tableHasColumn($conexion, 'ordenes_compra', 'Aprobada');
if (!$hasAprobada) {
$alterQuery = "ALTER TABLE ordenes_compra ADD COLUMN Aprobada TINYINT(1) DEFAULT 0";
if (!$conexion->query($alterQuery)) {
echo json_encode(['success' => false, 'error' => 'No se pudo corregir la estructura de la tabla: ' . $conexion->error]);
exit;
}
$hasAprobada = true;
}
$aprobada = in_array($estado, [1, 3], true) ? 1 : 0;
$conexion->begin_transaction();
try {
if ($hasEstado && $hasAprobada) {
$stmt = $conexion->prepare("UPDATE ordenes_compra SET Estado = ?, Aprobada = ? WHERE ID_Orden = ?");
if (!$stmt) {
throw new Exception('Error en la consulta SQL: ' . $conexion->error);
}
$stmt->bind_param('iii', $estado, $aprobada, $idOrden);
} elseif ($hasEstado) {
$stmt = $conexion->prepare("UPDATE ordenes_compra SET Estado = ? WHERE ID_Orden = ?");
if (!$stmt) {
throw new Exception('Error en la consulta SQL: ' . $conexion->error);
}
$stmt->bind_param('ii', $estado, $idOrden);
} else {
$stmt = $conexion->prepare("UPDATE ordenes_compra SET Aprobada = ? WHERE ID_Orden = ?");
if (!$stmt) {
throw new Exception('Error en la consulta SQL: ' . $conexion->error);
}
$stmt->bind_param('ii', $aprobada, $idOrden);
}
if (!$stmt->execute()) {
throw new Exception('No se pudo actualizar el estado: ' . $stmt->error);
}
$stmt->close();
if ($estado === 3) {
$productosStmt = $conexion->prepare("SELECT ID_Producto, Cantidad FROM ordenes_productos WHERE ID_Orden = ?");
if (!$productosStmt) {
throw new Exception('No se pudieron obtener los productos de la orden.');
}
$productosStmt->bind_param('i', $idOrden);
if (!$productosStmt->execute()) {
$productosStmt->close();
throw new Exception('No se pudieron leer los productos de la orden.');
}
$productosResult = $productosStmt->get_result();
$stockStmt = $conexion->prepare("UPDATE productos SET Stock_Disponible = Stock_Disponible + ? WHERE ID_Producto = ?");
if (!$stockStmt) {
$productosStmt->close();
throw new Exception('No se pudo preparar la actualización de stock.');
}
while ($producto = $productosResult->fetch_assoc()) {
$cantidad = intval($producto['Cantidad']);
$idProducto = intval($producto['ID_Producto']);
if ($cantidad > 0 && $idProducto > 0) {
$stockStmt->bind_param('ii', $cantidad, $idProducto);
if (!$stockStmt->execute()) {
$stockStmt->close();
$productosStmt->close();
throw new Exception('No se pudo actualizar el stock de los productos.');
}
}
}
$stockStmt->close();
$productosStmt->close();
}
$conexion->commit();
echo json_encode(['success' => true, 'message' => 'Estado de la orden actualizado correctamente.']);
} catch (Exception $e) {
$conexion->rollback();
echo json_encode(['success' => false, 'error' => $e->getMessage()]);
}
$conexion->close();
?>
+54
View File
@@ -0,0 +1,54 @@
<?php
session_start();
header('Content-Type: application/json');
if (!isset($_SESSION['id_usuario'])) {
echo json_encode(['success' => false, 'message' => 'Sesión no iniciada']);
exit();
}
$input = json_decode(file_get_contents('php://input'), true);
if (!$input) {
echo json_encode(['success' => false, 'message' => 'No se recibieron datos']);
exit();
}
require_once 'conexion.php';
$id = isset($input['id']) ? intval($input['id']) : 0;
$usuario = trim($input['usuario'] ?? '');
$correo = trim($input['correo'] ?? '');
$telefono = trim($input['telefono'] ?? '');
// Validar campos obligatorios (solo usuario es obligatorio)
if ($id <= 0 || empty($usuario)) {
echo json_encode(['success' => false, 'message' => 'Usuario es obligatorio']);
exit();
}
// Verificar que el usuario logueado sea el que intenta modificar su perfil
if ($id !== intval($_SESSION['id_usuario'])) {
echo json_encode(['success' => false, 'message' => 'No permitido']);
exit();
}
// Actualizar solo usuario, correo y teléfono
$query = "UPDATE usuarios SET Usuario = ?, Correo = ?, Telefono = ? WHERE ID_Usuario = ?";
$stmt = $conexion->prepare($query);
if (!$stmt) {
echo json_encode(['success' => false, 'message' => 'Error en consulta: ' . $conexion->error]);
exit();
}
$stmt->bind_param('sssi', $usuario, $correo, $telefono, $id);
if ($stmt->execute()) {
echo json_encode(['success' => true, 'message' => 'Perfil actualizado']);
} else {
echo json_encode(['success' => false, 'message' => 'Error al actualizar: ' . $stmt->error]);
}
$stmt->close();
$conexion->close();
?>
+46
View File
@@ -0,0 +1,46 @@
<?php
header('Content-Type: application/json');
$data = json_decode(file_get_contents('php://input'), true);
require_once 'conexion.php';
if ($conexion->connect_error) {
echo json_encode(['success' => false, 'error' => 'No hay conexión con la base de datos.']);
exit;
}
if (!isset($data['id']) || !isset($data['productos']) || !is_array($data['productos'])) {
echo json_encode(['success' => false, 'error' => 'Faltan datos requeridos.']);
exit;
}
$idOrden = intval($data['id']);
$stmt = $conexion->prepare("UPDATE ordenes_productos SET Cantidad = ? WHERE ID_Orden = ? AND ID_Producto = ?");
if (!$stmt) {
echo json_encode(['success' => false, 'error' => 'Error en la consulta SQL.']);
exit;
}
foreach ($data['productos'] as $producto) {
$idProducto = intval($producto['id']);
$cantidad = intval($producto['cantidad']);
if ($idProducto <= 0 || $cantidad <= 0) {
$stmt->close();
echo json_encode(['success' => false, 'error' => 'Datos de productos inválidos.']);
exit;
}
$stmt->bind_param('iii', $cantidad, $idOrden, $idProducto);
if (!$stmt->execute()) {
$stmt->close();
echo json_encode(['success' => false, 'error' => 'No se pudieron guardar los cambios.']);
exit;
}
}
$stmt->close();
$conexion->close();
echo json_encode(['success' => true, 'message' => 'Cantidades actualizadas correctamente.']);
?>
+55
View File
@@ -0,0 +1,55 @@
<?php
session_start();
require_once 'conexion.php';
header('Content-Type: application/json');
if ($_SERVER["REQUEST_METHOD"] != "POST") {
echo json_encode(['success' => false, 'message' => 'Método no permitido']);
exit();
}
$id = isset($_POST['id']) ? intval($_POST['id']) : 0;
$usuario = isset($_POST['usuario']) ? trim($_POST['usuario']) : '';
$contraseña = isset($_POST['contraseña']) ? trim($_POST['contraseña']) : '';
$confirmar_contraseña = isset($_POST['confirmar_contraseña']) ? trim($_POST['confirmar_contraseña']) : '';
$rol = isset($_POST['rol']) ? trim($_POST['rol']) : '';
$nombre = isset($_POST['nombre']) ? trim($_POST['nombre']) : '';
$apellido = isset($_POST['apellido']) ? trim($_POST['apellido']) : '';
$dni = isset($_POST['dni']) ? trim($_POST['dni']) : '';
$correo = isset($_POST['correo']) ? trim($_POST['correo']) : '';
$telefono = isset($_POST['telefono']) ? trim($_POST['telefono']) : '';
if ($id <= 0 || empty($usuario) || empty($contraseña) || !in_array($rol, ['admin', 'cantina', 'cancha']) || empty($nombre) || empty($apellido) || empty($dni)) {
echo json_encode(['success' => false, 'message' => 'Datos inválidos']);
exit();
}
if (strlen($contraseña) < 6) {
echo json_encode(['success' => false, 'message' => 'La contraseña debe tener al menos 6 carácteres']);
exit();
}
if ($contraseña !== $confirmar_contraseña) {
echo json_encode(['success' => false, 'message' => 'Las contraseñas no coinciden']);
exit();
}
$query = "UPDATE usuarios SET Usuario = ?, Contraseña = ?, Rol = ?, Nombre = ?, Apellido = ?, DNI = ?, Correo = ?, Telefono = ? WHERE ID_Usuario = ?";
$stmt = $conexion->prepare($query);
if (!$stmt) {
echo json_encode(['success' => false, 'message' => 'Error en consulta: ' . $conexion->error]);
exit();
}
$stmt->bind_param('ssssssssi', $usuario, $contraseña, $rol, $nombre, $apellido, $dni, $correo, $telefono, $id);
if ($stmt->execute()) {
echo json_encode(['success' => true, 'message' => 'Usuario actualizado']);
} else {
echo json_encode(['success' => false, 'message' => 'Error al actualizar: ' . $stmt->error]);
}
$stmt->close();
$conexion->close();
?>
+15
View File
@@ -0,0 +1,15 @@
<?php
$data = json_decode(file_get_contents("php://input"), true);
require_once 'conexion.php';
$descripcion = $data['descripcion'];
$precio_venta = $data['precio_venta'];
$precio_compra = $data['precio_compra'];
$cantidad = $data['cantidad'];
$stmt = $conexion->prepare("INSERT INTO productos (Descripcion, Precio_Venta, Precio_Compra, Stock_Disponible) VALUES (?, ?, ?, ?)");
$stmt->bind_param("sddi", $descripcion, $precio_venta, $precio_compra, $cantidad);
$stmt->execute();
echo "Producto agregado correctamente.";
?>
+18
View File
@@ -0,0 +1,18 @@
<?php
header('Content-Type: application/json');
require_once 'conexion.php';
$data = json_decode(file_get_contents("php://input"), true);
$idProveedor = $data['id_proveedor'] ?? 0;
$idProducto = $data['id_producto'] ?? 0;
$stmt = $conexion->prepare("INSERT INTO proveedores_productos (ID_Proveedor, ID_Producto) VALUES (?, ?)");
$stmt->bind_param("ii", $idProveedor, $idProducto);
if ($stmt->execute()) {
echo json_encode(['success' => true]);
} else {
echo json_encode(['success' => false, 'error' => $stmt->error]);
}
?>
+26
View File
@@ -0,0 +1,26 @@
<?php
header('Content-Type: application/json');
if (!isset($_GET['codigo'])) {
http_response_code(400);
echo json_encode(["error" => "Código no especificado"]);
exit;
}
$codigo = $_GET['codigo'];
require_once 'conexion.php';
if ($conexion->connect_error) {
http_response_code(500);
echo json_encode(["error" => "Error de conexión"]);
exit;
}
$stmt = $conexion->prepare("SELECT ID_Producto, Descripcion FROM productos WHERE ID_Producto = ?");
$stmt->bind_param("i", $codigo);
$stmt->execute();
$result = $stmt->get_result();
$producto = $result->fetch_assoc();
echo json_encode($producto ?: []);
?>
+41
View File
@@ -0,0 +1,41 @@
<?php
require_once 'conexion.php';
if (!isset($_GET['codigo']) || empty($_GET['codigo'])) {
echo json_encode(null);
exit;
}
$busqueda = trim($_GET['codigo']);
$terminoLike = "%" . $busqueda . "%";
// Detectamos si la búsqueda es un número (ID) o texto (descripción)
$esNumero = is_numeric($busqueda);
if ($esNumero) {
// Búsqueda por ID exacto
$sql = "SELECT ID_Producto, Descripcion, Precio_Venta, Stock_Disponible
FROM productos
WHERE ID_Producto = ?
LIMIT 1";
$stmt = $conexion->prepare($sql);
$busquedaInt = intval($busqueda);
$stmt->bind_param("i", $busquedaInt);
} else {
// Búsqueda por descripción (si contiene el texto)
$sql = "SELECT ID_Producto, Descripcion, Precio_Venta, Stock_Disponible
FROM productos
WHERE Descripcion LIKE ?
LIMIT 1";
$stmt = $conexion->prepare($sql);
$stmt->bind_param("s", $terminoLike);
}
$stmt->execute();
$result = $stmt->get_result();
$producto = $result->fetch_assoc();
echo json_encode($producto);
?>
+12
View File
@@ -0,0 +1,12 @@
<?php
$codigo = $_GET['codigo'];
require_once 'conexion.php';
$stmt = $conexion->prepare("SELECT Nombre, Telefono FROM proveedores WHERE ID_Proveedor = ?");
$stmt->bind_param("i", $codigo);
$stmt->execute();
$result = $stmt->get_result();
echo json_encode($result->fetch_assoc());
?>
+12
View File
@@ -0,0 +1,12 @@
<?php
$codigo = $_GET['id'];
require_once 'conexion.php';
$stmt = $conexion->prepare("SELECT ID_Proveedor, Nombre, Telefono FROM proveedores WHERE ID_Proveedor = ?");
$stmt->bind_param("i", $codigo);
$stmt->execute();
$result = $stmt->get_result();
echo json_encode($result->fetch_assoc());
?>
+91
View File
@@ -0,0 +1,91 @@
<?php
session_start();
header('Content-Type: application/json');
if (!isset($_SESSION['id_usuario'])) {
echo json_encode(['success' => false, 'message' => 'Sesión no iniciada']);
exit();
}
$input = json_decode(file_get_contents('php://input'), true);
if (!$input) {
echo json_encode(['success' => false, 'message' => 'No se recibieron datos']);
exit();
}
require_once 'conexion.php';
$id = isset($input['id']) ? intval($input['id']) : 0;
$contrasenia_actual = $input['contrasenia_actual'] ?? '';
$contrasenia_nueva = $input['contrasenia_nueva'] ?? '';
// Validar campos obligatorios
if ($id <= 0 || empty($contrasenia_actual) || empty($contrasenia_nueva)) {
echo json_encode(['success' => false, 'message' => 'Todos los campos son obligatorios']);
exit();
}
// Verificar que el usuario logueado sea el que intenta modificar su contraseña
if ($id !== intval($_SESSION['id_usuario'])) {
echo json_encode(['success' => false, 'message' => 'No permitido']);
exit();
}
// Obtener la contraseña actual del usuario
$query = "SELECT Contraseña FROM usuarios WHERE ID_Usuario = ?";
$stmt = $conexion->prepare($query);
if (!$stmt) {
echo json_encode(['success' => false, 'message' => 'Error en consulta: ' . $conexion->error]);
exit();
}
$stmt->bind_param('i', $id);
$stmt->execute();
$result = $stmt->get_result();
$usuario = $result->fetch_assoc();
if (!$usuario) {
echo json_encode(['success' => false, 'message' => 'Usuario no encontrado']);
exit();
}
// Verificar que la contraseña actual sea correcta
// En este sistema, las contraseñas se guardan en texto plano
if ($contrasenia_actual === $usuario['Contraseña']) {
// La contraseña actual es correcta
} else {
echo json_encode(['success' => false, 'message' => 'La contraseña actual es incorrecta']);
exit();
}
// Validar longitud mínima de la nueva contraseña
if (strlen($contrasenia_nueva) < 6) {
echo json_encode(['success' => false, 'message' => 'La contraseña debe tener al menos 6 caracteres']);
exit();
}
// Guardar la nueva contraseña en texto plano (compatible con el sistema actual)
$contrasenia_nueva_guardada = $contrasenia_nueva;
// Actualizar la contraseña
$update_query = "UPDATE usuarios SET Contraseña = ? WHERE ID_Usuario = ?";
$update_stmt = $conexion->prepare($update_query);
if (!$update_stmt) {
echo json_encode(['success' => false, 'message' => 'Error en consulta: ' . $conexion->error]);
exit();
}
$update_stmt->bind_param('si', $contrasenia_nueva_guardada, $id);
if ($update_stmt->execute()) {
echo json_encode(['success' => true, 'message' => 'Contraseña actualizada exitosamente']);
} else {
echo json_encode(['success' => false, 'message' => 'Error al actualizar: ' . $update_stmt->error]);
}
$update_stmt->close();
$stmt->close();
$conexion->close();
?>
+11
View File
@@ -0,0 +1,11 @@
<?php
session_start();
if (!isset($_SESSION['rol'])) {
header("Location: ../html/Login.html");
exit();
}
$rol = $_SESSION['rol']; // admin, cancha, cantina
$usuario = $_SESSION['usuario'] ?? '';
$usuarioId = $_SESSION['id_usuario'] ?? null;
include __DIR__ . '/../html/Cantina.html';
?>
+126
View File
@@ -0,0 +1,126 @@
<?php
require_once 'conexion.php';
header('Content-Type: application/json');
try {
$data = json_decode(file_get_contents('php://input'), true);
if (!isset($data['columna_actual']) || !isset($data['columna_nueva']) || !isset($data['monto'])) {
throw new Exception("Datos incompletos");
}
$columna_actual = trim($data['columna_actual']);
$columna_nueva = trim($data['columna_nueva']);
$monto = floatval($data['monto']);
$fecha_hoy = date('Y-m-d'); // Necesitamos la fecha de hoy para los periodos
// Validar datos
if (empty($columna_actual) || empty($columna_nueva) || $monto < 0) {
throw new Exception("Datos inválidos");
}
// Convertir nuevo nombre a formato de columna
$nombre_columna = strtolower(str_replace(' ', '_', $columna_nueva));
// Validar que sea un nombre válido para columna SQL
if (!preg_match('/^[a-z_][a-z0-9_]*$/', $nombre_columna)) {
throw new Exception("Nombre de gasto inválido");
}
// Si el nombre cambió, renombrar la columna primero
if (strtolower(str_replace(' ', '_', $columna_actual)) !== $nombre_columna) {
$columna_actual_formatted = strtolower(str_replace(' ', '_', $columna_actual));
// Verificar que la columna actual existe
$sql_check = "SHOW COLUMNS FROM gastos LIKE '" . $conexion->real_escape_string($columna_actual_formatted) . "'";
$result_check = $conexion->query($sql_check);
if ($result_check === false || $result_check->num_rows === 0) {
throw new Exception("La columna de gasto no existe: " . $conexion->error);
}
// Renombrar columna (Nota: esto cambia el nombre también en los registros históricos)
$sql_rename = "ALTER TABLE gastos CHANGE COLUMN `$columna_actual_formatted` `$nombre_columna` DECIMAL(10,2)";
if (!$conexion->query($sql_rename)) {
throw new Exception("Error al renombrar columna: " . $conexion->error);
}
} else {
$nombre_columna = strtolower(str_replace(' ', '_', $columna_actual));
}
// Obtener el registro actual COMPLETO
$sql_get_actual = "SELECT * FROM gastos WHERE Periodo_Hasta IS NULL ORDER BY Periodo_Desde DESC LIMIT 1";
$result_actual = $conexion->query($sql_get_actual);
if ($result_actual && $result_actual->num_rows > 0) {
$valores_anteriores = $result_actual->fetch_assoc();
$id_gasto_actual = $valores_anteriores['ID_Gasto'];
// 1. Cerrar el periodo actual poniendo la fecha de hoy
$sql_update = "UPDATE gastos SET Periodo_Hasta = ? WHERE ID_Gasto = ?";
$stmt_update = $conexion->prepare($sql_update);
$stmt_update->bind_param('si', $fecha_hoy, $id_gasto_actual);
if (!$stmt_update->execute()) {
throw new Exception("Error cerrando periodo anterior: " . $stmt_update->error);
}
$stmt_update->close();
// 2. Preparar el nuevo registro (INSERT)
$columnas = ['Periodo_Desde', 'Periodo_Hasta'];
$valores = [$fecha_hoy, null];
$placeholders = ['?', '?'];
$tipos = 'ss';
// Recorrer los valores del registro que acabamos de cerrar
foreach ($valores_anteriores as $col => $val) {
// Ignorar las columnas de control
if (in_array($col, ['ID_Gasto', 'Periodo_Desde', 'Periodo_Hasta'])) {
continue;
}
$columnas[] = "`$col`"; // Usamos backticks por seguridad en los nombres
// Si es la columna que estamos editando, guardamos el NUEVO monto. Si no, arrastramos el viejo.
if ($col === $nombre_columna) {
$valores[] = $monto;
} else {
$valores[] = floatval($val);
}
$placeholders[] = '?';
$tipos .= 'd';
}
// 3. Insertar la nueva "versión" de los gastos
$sql_insert = "INSERT INTO gastos (" . implode(', ', $columnas) . ") VALUES (" . implode(', ', $placeholders) . ")";
$stmt_insert = $conexion->prepare($sql_insert);
if (!$stmt_insert) {
throw new Exception("Error preparando INSERT: " . $conexion->error);
}
$stmt_insert->bind_param($tipos, ...$valores);
if (!$stmt_insert->execute()) {
throw new Exception("Error insertando el nuevo periodo: " . $stmt_insert->error);
}
$stmt_insert->close();
} else {
throw new Exception("No hay un periodo de gastos activo para editar.");
}
echo json_encode([
'success' => true,
'message' => 'Gasto editado y nuevo periodo registrado correctamente'
]);
} catch (Exception $e) {
echo json_encode([
'success' => false,
'message' => $e->getMessage()
]);
}
?>
+27
View File
@@ -0,0 +1,27 @@
<?php
header("Content-Type: application/json");
$data = json_decode(file_get_contents("php://input"), true);
if (!$data || !isset($data["id"])) {
echo json_encode(["success" => false, "error" => "Datos inválidos"]);
exit;
}
require_once 'conexion.php';
$id = $conexion->real_escape_string($data["id"]);
$descripcion = $conexion->real_escape_string($data["descripcion"]);
$precio_venta = floatval($data["precio_venta"]);
$precio_compra = floatval($data["precio_compra"]);
$cantidad = intval($data["cantidad"]);
$query = "UPDATE productos SET Descripcion=?, Precio_Venta=?, Precio_Compra=?, Stock_Disponible=? WHERE ID_Producto=?";
$stmt = $conexion->prepare($query);
$stmt->bind_param("sddii", $descripcion, $precio_venta, $precio_compra, $cantidad, $id);
if ($stmt->execute()) {
echo json_encode(["success" => true]);
} else {
echo json_encode(["success" => false, "error" => $conexion->error]);
}
+54
View File
@@ -0,0 +1,54 @@
<?php
header('Content-Type: application/json');
error_reporting(E_ALL);
ini_set("display_errors", 1);
require_once 'conexion.php';
if ($conexion->connect_error) {
echo json_encode([
"success" => false,
"error" => "Error de conexión: " . $conexion->connect_error
]);
exit;
}
$raw = file_get_contents("php://input");
// file_put_contents("log_debug.txt", "RAW:\n" . $raw . "\n", FILE_APPEND); <-- línea comentada / eliminada
$data = json_decode($raw, true);
if (!$data) {
echo json_encode([
"success" => false,
"error" => "JSON inválido",
"raw" => $raw
]);
exit;
}
$id = isset($data['id']) ? (int)$data['id'] : null;
$nombre = $data['nombre'] ?? null;
$telefono = $data['telefono'] ?? null;
if (!$id || !$nombre || !$telefono) {
echo json_encode(["success" => false, "error" => "Datos incompletos"]);
exit;
}
$stmt = $conexion->prepare("UPDATE proveedores SET Nombre = ?, Telefono = ? WHERE ID_Proveedor = ?");
if (!$stmt) {
echo json_encode(["success" => false, "error" => "Error en prepare(): " . $conexion->error]);
exit;
}
$stmt->bind_param("ssi", $nombre, $telefono, $id);
if ($stmt->execute()) {
echo json_encode(["success" => true]);
} else {
echo json_encode(["success" => false, "error" => $stmt->error]);
}
$stmt->close();
$conexion->close();
+48
View File
@@ -0,0 +1,48 @@
<?php
require_once 'conexion.php';
header('Content-Type: application/json');
try {
$data = json_decode(file_get_contents('php://input'), true);
if (!isset($data['columna'])) {
throw new Exception("Columna no especificada");
}
$columna = trim($data['columna']);
// Validar que sea un nombre válido
if (empty($columna)) {
throw new Exception("Columna inválida");
}
// Convertir nombre a formato de columna
$nombre_columna = strtolower(str_replace(' ', '_', $columna));
// Verificar que la columna existe
$sql_check = "SHOW COLUMNS FROM gastos LIKE '" . $conexion->real_escape_string($nombre_columna) . "'";
$result_check = $conexion->query($sql_check);
if ($result_check === false || $result_check->num_rows === 0) {
throw new Exception("La columna de gasto no existe:");
}
// Eliminar la columna
$sql_drop = "ALTER TABLE gastos DROP COLUMN `$nombre_columna`";
if (!$conexion->query($sql_drop)) {
throw new Exception("Error al eliminar columna: " . $conexion->error);
}
echo json_encode([
'success' => true,
'message' => 'Gasto eliminado correctamente'
]);
} catch (Exception $e) {
echo json_encode([
'success' => false,
'message' => $e->getMessage()
]);
}
?>
+68
View File
@@ -0,0 +1,68 @@
<?php
if (!isset($_GET['id'])) {
http_response_code(400);
echo json_encode(['success' => false, 'message' => 'ID de producto no especificado.']);
exit;
}
$id = intval($_GET['id']);
require_once 'conexion.php';
header('Content-Type: application/json');
// Verificar si la columna Estado existe
$checkColumn = $conexion->query("SHOW COLUMNS FROM productos WHERE Field='Estado'");
$columnaExists = $checkColumn && $checkColumn->num_rows > 0;
if ($columnaExists) {
// Soft delete: marcar el producto como inactivo
$conexion->query("SET FOREIGN_KEY_CHECKS=0");
$stmt = $conexion->prepare("UPDATE productos SET Estado = 0 WHERE ID_Producto = ?");
$stmt->bind_param("i", $id);
$stmt->execute();
$conexion->query("SET FOREIGN_KEY_CHECKS=1");
if ($stmt->affected_rows > 0) {
echo json_encode(['success' => true, 'message' => 'Producto eliminado correctamente.']);
} else {
echo json_encode(['success' => false, 'message' => 'Error al eliminar el producto o no existe.']);
}
} else {
// Fallback: verificar si la columna Activo existe
$checkColumnActivo = $conexion->query("SHOW COLUMNS FROM productos WHERE Field='Activo'");
$activoExists = $checkColumnActivo && $checkColumnActivo->num_rows > 0;
if ($activoExists) {
$conexion->query("SET FOREIGN_KEY_CHECKS=0");
$stmt = $conexion->prepare("UPDATE productos SET Activo = 0 WHERE ID_Producto = ?");
$stmt->bind_param("i", $id);
$stmt->execute();
$conexion->query("SET FOREIGN_KEY_CHECKS=1");
if ($stmt->affected_rows > 0) {
echo json_encode(['success' => true, 'message' => 'Producto eliminado correctamente.']);
} else {
echo json_encode(['success' => false, 'message' => 'Error al eliminar el producto o no existe.']);
}
} else {
$conexion->query("SET FOREIGN_KEY_CHECKS=0");
$stmt = $conexion->prepare("DELETE FROM productos WHERE ID_Producto = ?");
$stmt->bind_param("i", $id);
$stmt->execute();
$conexion->query("SET FOREIGN_KEY_CHECKS=1");
if ($stmt->affected_rows > 0) {
echo json_encode(['success' => true, 'message' => 'Producto eliminado correctamente.']);
} else {
echo json_encode(['success' => false, 'message' => 'Error al eliminar el producto o no existe.']);
}
}
}
?>
+15
View File
@@ -0,0 +1,15 @@
<?php
header('Content-Type: application/json');
require_once 'conexion.php';
$idProveedor = $_GET['id_proveedor'] ?? 0;
$idProducto = $_GET['id_producto'] ?? 0;
$stmt = $conexion->prepare("DELETE FROM proveedores_productos WHERE ID_Proveedor = ? AND ID_Producto = ?");
$stmt->bind_param("ii", $idProveedor, $idProducto);
if ($stmt->execute()) {
echo json_encode(['success' => true]);
} else {
echo json_encode(['success' => false, 'error' => $stmt->error]);
}
+73
View File
@@ -0,0 +1,73 @@
<?php
ini_set('display_errors', '0');
error_reporting(0);
header('Content-Type: application/json; charset=utf-8');
require_once 'conexion.php';
$rawInput = file_get_contents('php://input');
$id = 0;
if ($rawInput) {
$data = json_decode($rawInput, true);
if (json_last_error() === JSON_ERROR_NONE && isset($data['id'])) {
$id = intval($data['id']);
}
}
if (!$id && isset($_POST['id'])) {
$id = intval($_POST['id']);
}
if (!$id && isset($_GET['id'])) {
$id = intval($_GET['id']);
}
if ($conexion->connect_error) {
echo json_encode(['success' => false, 'error' => 'Error de conexión']);
exit;
}
if ($id <= 0) {
echo json_encode(['success' => false, 'error' => 'ID no proporcionado']);
exit;
}
$conexion->begin_transaction();
try {
$stmt = $conexion->prepare("DELETE FROM ordenes_productos WHERE ID_Orden IN (SELECT ID_Orden FROM ordenes_compra WHERE ID_Proveedor = ?)");
$stmt->bind_param("i", $id);
$stmt->execute();
$stmt->close();
$stmt = $conexion->prepare("DELETE FROM ordenes_compra WHERE ID_Proveedor = ?");
$stmt->bind_param("i", $id);
$stmt->execute();
$stmt->close();
$stmt = $conexion->prepare("DELETE FROM proveedores_productos WHERE ID_Proveedor = ?");
$stmt->bind_param("i", $id);
$stmt->execute();
$stmt->close();
$stmt = $conexion->prepare("DELETE FROM proveedores WHERE ID_Proveedor = ?");
$stmt->bind_param("i", $id);
$stmt->execute();
if ($stmt->affected_rows === 0) {
$stmt->close();
$conexion->rollback();
echo json_encode(['success' => false, 'error' => 'Proveedor no encontrado']);
exit;
}
$stmt->close();
$conexion->commit();
echo json_encode(['success' => true, 'message' => 'Proveedor eliminado']);
} catch (Exception $e) {
$conexion->rollback();
echo json_encode(['success' => false, 'error' => 'Error al eliminar proveedor: ' . $e->getMessage()]);
}
$conexion->close();
?>
+57
View File
@@ -0,0 +1,57 @@
<?php
session_start();
require_once 'conexion.php';
// Respuesta por defecto
header('Content-Type: application/json');
if ($_SERVER["REQUEST_METHOD"] != "POST") {
echo json_encode(['success' => false, 'message' => 'Método no permitido']);
exit();
}
// Obtener id del usuario a eliminar
$id = isset($_POST['id']) ? intval($_POST['id']) : 0;
if ($id <= 0) {
echo json_encode(['success' => false, 'message' => 'ID inválido']);
exit();
}
// Prevenir la eliminación del usuario actual (si es necesario)
if (isset($_SESSION['id_usuario']) && $_SESSION['id_usuario'] == $id) {
echo json_encode(['success' => false, 'message' => 'No puedes eliminar tu propia cuenta']);
exit();
}
// Obtener el ID del primer usuario registrado para protegerlo
$primerUsuarioQuery = "SELECT MIN(ID_Usuario) AS primer_id FROM usuarios";
$primerUsuarioStmt = $conexion->prepare($primerUsuarioQuery);
$primerUsuarioStmt->execute();
$primerUsuarioResult = $primerUsuarioStmt->get_result();
$primerUsuarioId = (int) $primerUsuarioResult->fetch_assoc()['primer_id'];
$primerUsuarioStmt->close();
if ($primerUsuarioId > 0 && $id === $primerUsuarioId) {
echo json_encode(['success' => false, 'message' => 'El administrador supremo no puede ser eliminado']);
exit();
}
// Eliminar el usuario
$query = "DELETE FROM usuarios WHERE ID_Usuario = ?";
$stmt = $conexion->prepare($query);
$stmt->bind_param("i", $id);
if ($stmt->execute()) {
if ($stmt->affected_rows > 0) {
echo json_encode(['success' => true, 'message' => 'Usuario eliminado exitosamente']);
} else {
echo json_encode(['success' => false, 'message' => 'El usuario no existe']);
}
} else {
echo json_encode(['success' => false, 'message' => 'Error al eliminar el usuario']);
}
$stmt->close();
$conexion->close();
?>
+41
View File
@@ -0,0 +1,41 @@
<?php
set_time_limit(120);
header('Content-Type: application/json');
$data = json_decode(file_get_contents('php://input'), true);
if (!isset($data['telefono']) || empty($data['telefono'])) {
echo json_encode(['success' => false, 'message' => 'Falta el teléfono']);
exit;
}
// 1. Limpiamos el número y le agregamos el 549 de Argentina si no lo tiene
$telefono = preg_replace('/[^0-9]/', '', $data['telefono']);
if (substr($telefono, 0, 3) !== '549') {
$telefono = '549' . ltrim($telefono, '0');
}
$nombre = $data['nombre'];
// 2. Generamos el código
$codigoGenerado = (string) rand(1000, 9999);
$mensaje = "Hola $nombre, tu código de verificación para Complejo Cap1tan es: *$codigoGenerado*";
// 3. Ejecutamos Python en SEGUNDO PLANO (Asíncrono para Windows)
$ruta_script = "C:\\xampp\\htdocs\\TP-Taller\\ProyectoTaller\\python\\Enviar_WSP.py";
// Armamos el comando base
$comando_python = escapeshellcmd("python \"$ruta_script\" \"$telefono\" \"$mensaje\"");
// "start /B" inicia el proceso sin abrir una nueva ventana de CMD.
// "1> NUL 2>&1" tira a la basura los mensajes de consola de Python para que PHP no se quede esperando a leerlos.
// popen() y pclose() abren el proceso y lo cierran al instante en PHP, dejando a Python trabajando solo.
pclose(popen("start /B " . $comando_python . " 1> NUL 2>&1", "r"));
// 4. Devolvemos la respuesta INMEDIATAMENTE al JavaScript
echo json_encode([
'success' => true,
'codigo' => $codigoGenerado,
'debug_python' => 'Ejecutando en segundo plano... (No se captura salida)'
]);
?>
+88
View File
@@ -0,0 +1,88 @@
<?php
require_once 'conexion.php';
header('Content-Type: application/json');
try {
// 1. OBTENER LAS COLUMNAS DINÁMICAMENTE
// Le preguntamos a la base de datos qué gastos existen actualmente
$sql_columnas = "SHOW COLUMNS FROM gastos";
$result_columnas = $conexion->query($sql_columnas);
if (!$result_columnas) {
throw new Exception("Error al obtener las columnas de gastos: " . $conexion->error);
}
$columnas_suma = [];
while ($row = $result_columnas->fetch_assoc()) {
$col = $row['Field'];
// Ignoramos las columnas de control de historial
if (!in_array($col, ['ID_Gasto', 'Periodo_Desde', 'Periodo_Hasta'])) {
// Usamos COALESCE por si algún valor es NULL, para que la suma matemática no falle
$columnas_suma[] = "COALESCE(g.`$col`, 0)";
}
}
// Armamos el fragmento de la suma: "COALESCE(g.sueldo,0) + COALESCE(g.luz,0)..."
$suma_gastos_sql = empty($columnas_suma) ? "0" : implode(' + ', $columnas_suma);
// 2. CONSTRUIR LA CONSULTA PRINCIPAL
// Usamos LAST_DAY() para asegurar que tomamos la versión de gastos de fin de mes
// y evitamos duplicar los ingresos si hubo cambios a mitad de mes.
$sql_reporte = "
SELECT
ingresos.Mes,
COALESCE(ingresos.Ingreso_Bruto, 0) AS Ingreso_Bruto,
COALESCE(ingresos.Costo, 0) AS Costo,
COALESCE(ingresos.Ganancia_Bruta, 0) AS Ganancia_Bruta,
($suma_gastos_sql) AS Gastos_Totales,
COALESCE(ingresos.Ganancia_Bruta, 0) - ($suma_gastos_sql) AS Ganancia_Neta
FROM (
SELECT
DATE_FORMAT(v.Fecha, '%Y-%m') AS Mes,
LAST_DAY(MAX(v.Fecha)) AS Fin_De_Mes,
SUM(p.Precio_Venta * vp.Cantidad) AS Ingreso_Bruto,
SUM(p.Precio_Compra * vp.Cantidad) AS Costo,
SUM((p.Precio_Venta - p.Precio_Compra) * vp.Cantidad) AS Ganancia_Bruta
FROM ventas v
JOIN ventas_productos vp ON v.ID_Venta = vp.ID_Venta
JOIN productos p ON vp.ID_Producto = p.ID_Producto
GROUP BY Mes
) ingresos
LEFT JOIN gastos g
ON g.Periodo_Desde <= ingresos.Fin_De_Mes
AND (g.Periodo_Hasta IS NULL OR g.Periodo_Hasta > ingresos.Fin_De_Mes)
ORDER BY ingresos.Mes DESC;
";
// 3. EJECUTAR LA CONSULTA
$result_reporte = $conexion->query($sql_reporte);
if (!$result_reporte) {
throw new Exception("Error al generar el reporte: " . $conexion->error);
}
$reporte = [];
while ($row = $result_reporte->fetch_assoc()) {
// Convertimos los valores numéricos de strings a floats para el JSON
$reporte[] = [
'Mes' => $row['Mes'],
'Ingreso_Bruto' => floatval($row['Ingreso_Bruto']),
'Costo' => floatval($row['Costo']),
'Ganancia_Bruta' => floatval($row['Ganancia_Bruta']),
'Gastos_Totales' => floatval($row['Gastos_Totales']),
'Ganancia_Neta' => floatval($row['Ganancia_Neta'])
];
}
echo json_encode([
'success' => true,
'data' => $reporte
]);
} catch (Exception $e) {
echo json_encode([
'success' => false,
'message' => $e->getMessage()
]);
}
?>
+26
View File
@@ -0,0 +1,26 @@
<?php
header('Content-Type: application/json');
require_once 'conexion.php';
if ($conexion->connect_error) {
echo json_encode(['success' => false, 'error' => 'Error de conexión']);
exit;
}
$data = json_decode(file_get_contents("php://input"), true);
$nombre = $data['nombre'] ?? '';
$telefono = $data['telefono'] ?? '';
$stmt = $conexion->prepare("INSERT INTO proveedores (Nombre, Telefono) VALUES (?, ?)");
$stmt->bind_param("ss", $nombre, $telefono);
if ($stmt->execute()) {
echo json_encode(['success' => true]);
} else {
echo json_encode(['success' => false, 'error' => $conexion->error]);
}
$stmt->close();
$conexion->close();
?>
+225
View File
@@ -0,0 +1,225 @@
<?php
session_start();
require_once 'conexion.php';
header('Content-Type: application/json');
// Obtener datos del POST
$data = json_decode(file_get_contents("php://input"), true);
if (!$data) {
echo json_encode([
'success' => false,
'message' => 'Datos no recibidos'
]);
exit;
}
$nombre = isset($data['nombre']) ? trim($data['nombre']) : '';
$telefono = isset($data['telefono']) ? trim($data['telefono']) : '';
$dni = isset($data['dni']) ? trim($data['dni']) : '';
$fecha = isset($data['fecha']) ? $data['fecha'] : '';
$horario = isset($data['horario']) ? $data['horario'] : '';
$tipo = isset($data['tipo']) ? $data['tipo'] : '';
$numeroCancha = isset($data['numeroCancha']) ? intval($data['numeroCancha']) : 0;
$monto = isset($data['monto']) ? floatval($data['monto']) : 0;
$incluirQuincho = isset($data['incluirQuincho']) ? $data['incluirQuincho'] : false;
$montoQuincho = isset($data['montoQuincho']) ? floatval($data['montoQuincho']) : 0;
$idCancha = isset($data['idCancha']) ? intval($data['idCancha']) : null;
// Validar datos requeridos
if (empty($nombre) || empty($telefono) || empty($dni) || empty($fecha) || empty($horario) || empty($tipo) || $numeroCancha === 0 || $monto === 0) {
echo json_encode([
'success' => false,
'message' => 'Datos incompletos'
]);
exit;
}
try {
// Escapar datos para evitar SQL injection
$nombre = mysqli_real_escape_string($conexion, $nombre);
$telefono = mysqli_real_escape_string($conexion, $telefono);
$dni = mysqli_real_escape_string($conexion, $dni);
$fecha = mysqli_real_escape_string($conexion, $fecha);
$horario = mysqli_real_escape_string($conexion, $horario);
$tipo = mysqli_real_escape_string($conexion, $tipo);
// Buscar o crear cliente
$sqlBuscarCliente = "SELECT ID_Cliente FROM clientes WHERE DNI = '$dni'";
$resBuscar = mysqli_query($conexion, $sqlBuscarCliente);
if (!$resBuscar) {
throw new Exception("Error al buscar cliente: " . mysqli_error($conexion));
}
$cliente = mysqli_fetch_assoc($resBuscar);
if ($cliente) {
// Cliente existe, actualizar datos
$idCliente = $cliente['ID_Cliente'];
$sqlActualizarCliente = "UPDATE clientes SET Nombre = '$nombre', Telefono = '$telefono' WHERE ID_Cliente = $idCliente";
if (!mysqli_query($conexion, $sqlActualizarCliente)) {
throw new Exception("Error al actualizar cliente: " . mysqli_error($conexion));
}
} else {
// Crear nuevo cliente
$sqlCrearCliente = "INSERT INTO clientes (Nombre, Telefono, DNI) VALUES ('$nombre', '$telefono', '$dni')";
if (!mysqli_query($conexion, $sqlCrearCliente)) {
throw new Exception("Error al crear cliente: " . mysqli_error($conexion));
}
$idCliente = mysqli_insert_id($conexion);
}
// Obtener los datos de la cancha usada para calcular el cupón
$sqlObtenerCancha = "SELECT ID_Cancha, Cant_Reservas_Cupon, Descuento_Cupon, Cant_Faltas, Duracion_Cupon FROM canchas WHERE Tipo = '$tipo' LIMIT 1";
$resCancha = mysqli_query($conexion, $sqlObtenerCancha);
if (!$resCancha) {
throw new Exception("Error al obtener cancha: " . mysqli_error($conexion));
}
$cancha = mysqli_fetch_assoc($resCancha);
if (!$cancha) {
throw new Exception("No existe cancha del tipo especificado");
}
$idCancha = $cancha['ID_Cancha'];
$umbral = intval($cancha['Cant_Reservas_Cupon']);
$descuentoCupon = floatval($cancha['Descuento_Cupon']);
$maxFaltas = intval($cancha['Cant_Faltas']);
$duracionCupon = intval($cancha['Duracion_Cupon']);
// Buscar fila de cupón existente para el cliente y tipo de cancha
$sqlBuscarCupon = "SELECT ID_Cupon, Cantidad_Reservas, Cantidad_Faltas, Ultima_Fecha, Descuento FROM cupones WHERE ID_Cliente = $idCliente AND Tipo = '$tipo' LIMIT 1";
$resCupon = mysqli_query($conexion, $sqlBuscarCupon);
if (!$resCupon) {
throw new Exception("Error al buscar cupón: " . mysqli_error($conexion));
}
$cupon = mysqli_fetch_assoc($resCupon);
if (!$cupon) {
$sqlCrearCupon = "INSERT INTO cupones (Cantidad_Reservas, Cantidad_Faltas, Tipo, Ultima_Fecha, Descuento, ID_Cliente) VALUES (0, 0, '$tipo', NULL, 0, $idCliente)";
if (!mysqli_query($conexion, $sqlCrearCupon)) {
throw new Exception("Error al crear cupón: " . mysqli_error($conexion));
}
$cupon = [
'ID_Cupon' => mysqli_insert_id($conexion),
'Cantidad_Reservas' => 0,
'Cantidad_Faltas' => 0,
'Ultima_Fecha' => null,
'Descuento' => 0
];
}
$cantidadReservasCupon = intval($cupon['Cantidad_Reservas']);
$cantidadFaltasCupon = intval($cupon['Cantidad_Faltas']);
$ultimaFechaCupon = $cupon['Ultima_Fecha'];
// Caducidad del cupón
if ($duracionCupon > 0 && !empty($ultimaFechaCupon)) {
$fechaUltima = new DateTime($ultimaFechaCupon);
$fechaUltima->modify("+{$duracionCupon} days");
$fechaActual = new DateTime();
if ($fechaActual > $fechaUltima) {
$cantidadReservasCupon = 0;
$cantidadFaltasCupon = 0;
$ultimaFechaCupon = null;
$sqlResetCupon = "UPDATE cupones SET Cantidad_Reservas = 0, Cantidad_Faltas = 0, Ultima_Fecha = NULL, Descuento = 0 WHERE ID_Cupon = {$cupon['ID_Cupon']}";
if (!mysqli_query($conexion, $sqlResetCupon)) {
throw new Exception("Error al resetear cupón vencido: " . mysqli_error($conexion));
}
}
}
// Si la cantidad de faltas supera el máximo permitido, reiniciamos el conteo de reservas
if ($maxFaltas > 0 && $cantidadFaltasCupon > $maxFaltas) {
$cantidadReservasCupon = 0;
$cantidadFaltasCupon = 0;
$ultimaFechaCupon = null;
$sqlResetCupon = "UPDATE cupones SET Cantidad_Reservas = 0, Cantidad_Faltas = 0, Ultima_Fecha = NULL, Descuento = 0 WHERE ID_Cupon = {$cupon['ID_Cupon']}";
if (!mysqli_query($conexion, $sqlResetCupon)) {
throw new Exception("Error al resetear cupón por faltas: " . mysqli_error($conexion));
}
}
// Convertir horario a formato DATETIME
$fechaHora = $fecha . ' ' . $horario . ':00';
$descuentoAplicado = 0;
$montoFinal = $monto;
$valorCupon = $descuentoCupon;
if ($umbral > 0 && ($cantidadReservasCupon + 1) >= $umbral) {
$descuentoAplicado = $valorCupon;
$montoFinal = round($monto * (1 - $descuentoAplicado), 2);
$cantidadReservasCupon = 0;
$cantidadFaltasCupon = 0;
$ultimaFechaCupon = date('Y-m-d H:i:s');
} else {
$cantidadReservasCupon += 1;
$ultimaFechaCupon = date('Y-m-d H:i:s');
}
$sqlActualizarCupon = "UPDATE cupones SET Cantidad_Reservas = $cantidadReservasCupon, Cantidad_Faltas = $cantidadFaltasCupon, Ultima_Fecha = " . ($ultimaFechaCupon ? "'$ultimaFechaCupon'" : "NULL") . ", Descuento = $descuentoAplicado WHERE ID_Cupon = {$cupon['ID_Cupon']}";
if (!mysqli_query($conexion, $sqlActualizarCupon)) {
throw new Exception("Error al actualizar cupón: " . mysqli_error($conexion));
}
// Obtener ID del usuario desde la sesión
$id_usuario = isset($_SESSION['id_usuario']) ? intval($_SESSION['id_usuario']) : null;
// Insertar reserva de cancha
$sqlInsertarReserva = "INSERT INTO reservas (Fecha_Hora, Monto, Numero, Estado, ID_Cliente, ID_Cancha, Descuento, ID_Usuario)
VALUES ('$fechaHora', $montoFinal, $numeroCancha, 0, $idCliente, $idCancha, $descuentoAplicado, $id_usuario)";
if (!mysqli_query($conexion, $sqlInsertarReserva)) {
throw new Exception("Error al insertar reserva: " . mysqli_error($conexion));
}
$idReserva = mysqli_insert_id($conexion);
// Si incluye quincho, insertar reserva de quincho
if ($incluirQuincho && $montoQuincho > 0) {
// Obtener ID_Cancha para quincho
$sqlObtenerQuincho = "SELECT ID_Cancha FROM canchas WHERE Tipo = 'Q'";
$resQuincho = mysqli_query($conexion, $sqlObtenerQuincho);
if (!$resQuincho) {
throw new Exception("Error al obtener quincho: " . mysqli_error($conexion));
}
$quincho = mysqli_fetch_assoc($resQuincho);
if ($quincho) {
$idQuincho = $quincho['ID_Cancha'];
// El quincho se reserva por el día completo, entonces el número es 1 (hay un solo quincho)
$sqlInsertarQuincho = "INSERT INTO reservas (Fecha_Hora, Monto, Numero, Estado, ID_Cliente, ID_Cancha, Descuento, ID_Usuario)
VALUES ('$fechaHora', $montoQuincho, 1, 0, $idCliente, $idQuincho, 0, $id_usuario)";
if (!mysqli_query($conexion, $sqlInsertarQuincho)) {
throw new Exception("Error al insertar reserva de quincho: " . mysqli_error($conexion));
}
}
}
echo json_encode([
'success' => true,
'message' => 'Reserva confirmada exitosamente',
'id_reserva' => $idReserva,
'id_cliente' => $idCliente
]);
} catch (Exception $e) {
echo json_encode([
'success' => false,
'message' => $e->getMessage()
]);
}
?>
+106
View File
@@ -0,0 +1,106 @@
<?php
session_start();
require_once 'conexion.php';
// Respuesta por defecto
header('Content-Type: application/json');
if ($_SERVER["REQUEST_METHOD"] != "POST") {
echo json_encode(['success' => false, 'message' => 'Método no permitido']);
exit();
}
if ($conexion->connect_error) {
echo json_encode(['success' => false, 'message' => 'Error de conexión a la base de datos: ' . $conexion->connect_error]);
exit();
}
// Obtener datos del formulario
$usuario = isset($_POST['usuario']) ? trim($_POST['usuario']) : '';
$contraseña = isset($_POST['contraseña']) ? trim($_POST['contraseña']) : '';
$confirmar_contraseña = isset($_POST['confirmar_contraseña']) ? trim($_POST['confirmar_contraseña']) : '';
$rol = isset($_POST['rol']) ? trim($_POST['rol']) : '';
$nombre = isset($_POST['nombre']) ? trim($_POST['nombre']) : '';
$apellido = isset($_POST['apellido']) ? trim($_POST['apellido']) : '';
$dni = isset($_POST['dni']) ? trim($_POST['dni']) : '';
$correo = isset($_POST['correo']) ? trim($_POST['correo']) : '';
$telefono = isset($_POST['telefono']) ? trim($_POST['telefono']) : '';
// El primer usuario registrado será el administrador supremo del sistema
$contadorQuery = "SELECT COUNT(*) AS total FROM usuarios";
$contadorStmt = $conexion->prepare($contadorQuery);
$contadorStmt->execute();
$contadorResult = $contadorStmt->get_result();
$primerUsuario = $contadorResult->fetch_assoc()['total'] == 0;
$contadorStmt->close();
if ($primerUsuario) {
$rol = 'admin';
}
// Log para debugging
error_log("Datos recibidos - Usuario: $usuario, Rol: $rol, Nombre: $nombre");
// Validar que los campos requeridos estén presentes
if (empty($usuario) || empty($contraseña) || empty($confirmar_contraseña) || empty($rol) || empty($nombre) || empty($apellido) || empty($dni)) {
echo json_encode(['success' => false, 'message' => 'Todos los campos requeridos deben estar completos']);
exit();
}
if (strlen($contraseña) < 6) {
echo json_encode(['success' => false, 'message' => 'La contraseña debe tener al menos 6 carácteres']);
exit();
}
if ($contraseña !== $confirmar_contraseña) {
echo json_encode(['success' => false, 'message' => 'Las contraseñas no coinciden']);
exit();
}
// Validar que el rol sea válido
if (!in_array($rol, ['admin', 'cantina', 'cancha'])) {
echo json_encode(['success' => false, 'message' => 'Rol inválido']);
exit();
}
// Verificar si el usuario ya existe
$query = "SELECT ID_Usuario FROM usuarios WHERE Usuario = ?";
$stmt = $conexion->prepare($query);
if (!$stmt) {
echo json_encode(['success' => false, 'message' => 'Error en la consulta: ' . $conexion->error]);
exit();
}
$stmt->bind_param("s", $usuario);
$stmt->execute();
$result = $stmt->get_result();
if ($result->num_rows > 0) {
echo json_encode(['success' => false, 'message' => 'El usuario ya existe']);
$stmt->close();
exit();
}
$stmt->close();
// Insertar el nuevo usuario
$query = "INSERT INTO usuarios (Usuario, Contraseña, Rol, Nombre, Apellido, DNI, Correo, Telefono)
VALUES (?, ?, ?, ?, ?, ?, ?, ?)";
$stmt = $conexion->prepare($query);
if (!$stmt) {
echo json_encode(['success' => false, 'message' => 'Error en la consulta: ' . $conexion->error]);
exit();
}
$stmt->bind_param("ssssssss", $usuario, $contraseña, $rol, $nombre, $apellido, $dni, $correo, $telefono);
if ($stmt->execute()) {
echo json_encode(['success' => true, 'message' => 'Usuario registrado exitosamente', 'id' => $stmt->insert_id]);
} else {
echo json_encode(['success' => false, 'message' => 'Error al registrar el usuario: ' . $stmt->error]);
}
$stmt->close();
$conexion->close();
?>
+39
View File
@@ -0,0 +1,39 @@
<?php
session_start();
require_once 'conexion.php';
if ($conexion->connect_error) {
die("Error de conexión: " . $conexion->connect_error);
}
if ($_SERVER["REQUEST_METHOD"] == "POST") {
header('Content-Type: application/json');
$usuario = $_POST['usuario'];
$clave = $_POST['clave'];
$query = "SELECT * FROM usuarios WHERE Usuario=? AND Contraseña=?";
$stmt = $conexion->prepare($query);
$stmt->bind_param("ss", $usuario, $clave);
$stmt->execute();
$result = $stmt->get_result();
if ($result->num_rows == 1) {
$row = $result->fetch_assoc();
$_SESSION['id_usuario'] = $row['ID_Usuario'] ?? null;
$_SESSION['usuario'] = $row['Usuario'];
$_SESSION['rol'] = $row['Rol']; // admin, cancha o cantina
echo json_encode([
'success' => true,
'message' => 'Login exitoso'
]);
exit();
} else {
echo json_encode([
'success' => false,
'message' => 'Usuario o contraseña incorrectos'
]);
exit();
}
}
?>
+16
View File
@@ -0,0 +1,16 @@
<?php
session_start();
header('Content-Type: application/json');
$_SESSION = [];
if (ini_get('session.use_cookies')) {
$params = session_get_cookie_params();
setcookie(session_name(), '', time() - 42000,
$params['path'], $params['domain'],
$params['secure'], $params['httponly']
);
}
session_destroy();
echo json_encode(['success' => true]);
?>
+51
View File
@@ -0,0 +1,51 @@
<?php
require_once 'conexion.php';
try {
// Verificar y agregar las columnas necesarias a la tabla gastos
$columnas_necesarias = [
'Sueldo' => 'DECIMAL(10,2) DEFAULT 0',
'Luz' => 'DECIMAL(10,2) DEFAULT 0',
'Agua' => 'DECIMAL(10,2) DEFAULT 0',
'Impuestos' => 'DECIMAL(10,2) DEFAULT 0'
];
foreach ($columnas_necesarias as $nombre_columna => $tipo_columna) {
// Verificar si la columna existe
$result = $conexion->query("SHOW COLUMNS FROM gastos LIKE '$nombre_columna'");
if ($result->num_rows === 0) {
// Si no existe, agregarla
$sql = "ALTER TABLE gastos ADD COLUMN `$nombre_columna` $tipo_columna";
if ($conexion->query($sql)) {
echo "✓ Columna '$nombre_columna' agregada correctamente\n";
} else {
throw new Exception("Error al agregar columna '$nombre_columna': " . $conexion->error);
}
} else {
echo "✓ Columna '$nombre_columna' ya existe\n";
}
}
// Verificar que haya al menos un registro de gastos
$result = $conexion->query("SELECT COUNT(*) as count FROM gastos");
$count = $result->fetch_assoc()['count'];
if ($count === 0) {
// Insertar un registro de gasto por defecto si no existe
$sql = "INSERT INTO gastos (Periodo_Desde, Periodo_Hasta, Sueldo, Luz, Agua, Impuestos)
VALUES (CURDATE(), NULL, 0, 0, 0, 0)";
if ($conexion->query($sql)) {
echo "✓ Registro de gasto inicial creado\n";
} else {
throw new Exception("Error al crear registro inicial: " . $conexion->error);
}
}
echo "\n✓ Migración de gastos completada exitosamente\n";
echo json_encode(['success' => true, 'message' => 'Migración completada']);
} catch (Exception $e) {
echo json_encode(['success' => false, 'error' => $e->getMessage()]);
}
?>
+45
View File
@@ -0,0 +1,45 @@
<?php
require_once 'conexion.php';
// Verificar si la columna ya existe
$result = $conexion->query("SHOW COLUMNS FROM ventas_productos LIKE 'Precio_Unitario'");
if ($result->num_rows === 0) {
// Si no existe, agregarla
$sql = "ALTER TABLE ventas_productos ADD COLUMN Precio_Unitario DECIMAL(10, 2) DEFAULT 0.00";
if ($conexion->query($sql) === TRUE) {
// Actualizar con los precios de los productos existentes
$update_sql = "
UPDATE ventas_productos vp
JOIN productos p ON vp.ID_Producto = p.ID_Producto
SET vp.Precio_Unitario = p.Precio
WHERE vp.Precio_Unitario = 0
";
if ($conexion->query($update_sql) === TRUE) {
echo json_encode([
'success' => true,
'message' => 'Columna Precio_Unitario agregada y actualizada correctamente'
]);
} else {
echo json_encode([
'success' => false,
'message' => 'Error al actualizar precios: ' . $conexion->error
]);
}
} else {
echo json_encode([
'success' => false,
'message' => 'Error al agregar columna: ' . $conexion->error
]);
}
} else {
echo json_encode([
'success' => true,
'message' => 'La columna Precio_Unitario ya existe'
]);
}
$conexion->close();
?>
+28
View File
@@ -0,0 +1,28 @@
<?php
require_once 'conexion.php';
header('Content-Type: application/json');
try {
$sql = "SELECT c.ID_Cancha, c.Tipo, c.Precio, c.Duracion, c.Cant_Canchas,
c.Cant_Reservas_Cupon, c.Descuento_Cupon, c.Cant_Faltas, c.Duracion_Cupon,
h.Hora_Apertura, h.Hora_Cierre
FROM canchas c
LEFT JOIN horarios h ON h.Dia = 'Lunes a Viernes'
WHERE c.Tipo IN ('F', 'P', 'Q')";
$res = mysqli_query($conexion, $sql);
if (!$res) {
throw new Exception("Error en la consulta de canchas: " . mysqli_error($conexion));
}
$canchas = mysqli_fetch_all($res, MYSQLI_ASSOC);
echo json_encode($canchas);
} catch (Exception $e) {
echo json_encode([
'success' => false,
'message' => $e->getMessage()
]);
}
?>
+89
View File
@@ -0,0 +1,89 @@
<?php
require_once 'conexion.php';
header('Content-Type: application/json');
$fecha = isset($_GET['fecha']) ? $_GET['fecha'] : '';
$horario_inicio = isset($_GET['horario']) ? $_GET['horario'] : '';
$duracion = isset($_GET['duracion']) ? $_GET['duracion'] : 60;
$tipo = isset($_GET['tipo']) ? $_GET['tipo'] : '';
if (empty($fecha) || empty($horario_inicio) || empty($tipo)) {
echo json_encode([
'success' => false,
'message' => 'Parámetros incompletos'
]);
exit;
}
try {
// Obtener la cantidad total de canchas del tipo especificado
$t = mysqli_real_escape_string($conexion, $tipo);
$sqlCanchas = "SELECT Cant_Canchas as cantidad_canchas, Duracion as duracion_cancha
FROM canchas
WHERE Tipo = '$t'";
$resCanchas = mysqli_query($conexion, $sqlCanchas);
if (!$resCanchas) {
throw new Exception("Error al obtener información de canchas: " . mysqli_error($conexion));
}
$cancha = mysqli_fetch_assoc($resCanchas);
$cantidadCanchas = $cancha['cantidad_canchas'];
$duracionCancha = $cancha['duracion_cancha'];
// Convertir horario
$horaInicioArr = explode(':', $horario_inicio);
$horaInicioMin = intval($horaInicioArr[0]) * 60 + intval($horaInicioArr[1]);
$horaFinMin = $horaInicioMin + intval($duracion);
$horaInicio = $horario_inicio . ':00';
$horaFin = sprintf("%02d:%02d", intval($horaFinMin / 60), intval($horaFinMin % 60)) . ':00';
// Obtener las canchas reservadas para este horario
$f = mysqli_real_escape_string($conexion, $fecha);
$sqlReservadasPorNumero = "SELECT r.Numero as numero_cancha
FROM reservas r
INNER JOIN canchas c ON r.ID_Cancha = c.ID_Cancha
WHERE c.Tipo = '$t'
AND DATE(r.Fecha_Hora) = '$f'
AND r.Estado != 2
AND (
(TIME(r.Fecha_Hora) < '$horaFin' AND ADDTIME(TIME(r.Fecha_Hora), SEC_TO_TIME($duracionCancha * 60)) > '$horaInicio')
)
GROUP BY r.Numero";
$resReservadasPorNumero = mysqli_query($conexion, $sqlReservadasPorNumero);
if (!$resReservadasPorNumero) {
throw new Exception("Error al obtener canchas reservadas: " . mysqli_error($conexion));
}
$canchasReservadas = [];
while ($row = mysqli_fetch_assoc($resReservadasPorNumero)) {
$canchasReservadas[] = intval($row['numero_cancha']);
}
// Construir lista de todas las canchas con su disponibilidad
$canchas = [];
for ($i = 1; $i <= $cantidadCanchas; $i++) {
$canchas[] = [
'numero' => $i,
'disponible' => !in_array($i, $canchasReservadas)
];
}
echo json_encode([
'success' => true,
'cantidad_total' => $cantidadCanchas,
'canchas' => $canchas,
'tipo' => $tipo
]);
} catch (Exception $e) {
echo json_encode([
'success' => false,
'message' => $e->getMessage()
]);
}
?>
+136
View File
@@ -0,0 +1,136 @@
<?php
require_once 'conexion.php';
header('Content-Type: application/json');
$dni = isset($_GET['dni']) ? trim($_GET['dni']) : '';
$tipo = isset($_GET['tipo']) ? trim($_GET['tipo']) : '';
if (empty($dni) || empty($tipo)) {
echo json_encode(['success' => false, 'message' => 'DNI y tipo de cancha son requeridos']);
exit;
}
$tipoDb = '';
if ($tipo === 'futbol' || $tipo === 'F') {
$tipoDb = 'F';
} elseif ($tipo === 'padel' || $tipo === 'P') {
$tipoDb = 'P';
}
if (empty($tipoDb)) {
echo json_encode(['success' => false, 'message' => 'Tipo de cancha inválido']);
exit;
}
$dni = mysqli_real_escape_string($conexion, $dni);
$sqlCliente = "SELECT ID_Cliente FROM clientes WHERE DNI = '$dni' LIMIT 1";
$resCliente = mysqli_query($conexion, $sqlCliente);
if (!$resCliente) {
echo json_encode(['success' => false, 'message' => 'Error al buscar cliente: ' . mysqli_error($conexion)]);
exit;
}
$cliente = mysqli_fetch_assoc($resCliente);
if (!$cliente) {
echo json_encode([
'success' => true,
'clienteEncontrado' => false,
'cantidadReservas' => 0,
'cantidadFaltas' => 0,
'umbral' => 0,
'descuentoCanchas' => 0,
'duracionCupon' => 0,
'ultimaFecha' => null,
'aplicarDescuento' => false,
'reservasRestantes' => null
]);
exit;
}
$idCliente = intval($cliente['ID_Cliente']);
$sqlCancha = "SELECT Cant_Reservas_Cupon, Descuento_Cupon, Cant_Faltas, Duracion_Cupon FROM canchas WHERE Tipo = '$tipoDb' LIMIT 1";
$resCancha = mysqli_query($conexion, $sqlCancha);
if (!$resCancha) {
echo json_encode(['success' => false, 'message' => 'Error al obtener datos de la cancha: ' . mysqli_error($conexion)]);
exit;
}
$cancha = mysqli_fetch_assoc($resCancha);
if (!$cancha) {
echo json_encode(['success' => false, 'message' => 'No se encontró el tipo de cancha']);
exit;
}
$umbral = intval($cancha['Cant_Reservas_Cupon']);
$descuentoCanchas = floatval($cancha['Descuento_Cupon']);
$duracionCupon = intval($cancha['Duracion_Cupon']);
$maxFaltas = intval($cancha['Cant_Faltas']);
$sqlCupon = "SELECT ID_Cupon, Cantidad_Reservas, Cantidad_Faltas, Ultima_Fecha FROM cupones WHERE ID_Cliente = $idCliente AND Tipo = '$tipoDb' LIMIT 1";
$resCupon = mysqli_query($conexion, $sqlCupon);
if (!$resCupon) {
echo json_encode(['success' => false, 'message' => 'Error al buscar cupón: ' . mysqli_error($conexion)]);
exit;
}
$cupon = mysqli_fetch_assoc($resCupon);
$cantidadReservas = 0;
$cantidadFaltas = 0;
$ultimaFecha = null;
$vencido = false;
if ($cupon) {
$cantidadReservas = intval($cupon['Cantidad_Reservas']);
$cantidadFaltas = intval($cupon['Cantidad_Faltas']);
$ultimaFecha = $cupon['Ultima_Fecha'];
if ($duracionCupon > 0 && !empty($ultimaFecha)) {
$fechaUltima = new DateTime($ultimaFecha);
$fechaUltima->modify("+{$duracionCupon} days");
$fechaActual = new DateTime();
if ($fechaActual > $fechaUltima) {
$cantidadReservas = 0;
$cantidadFaltas = 0;
$ultimaFecha = null;
$vencido = true;
$sqlResetCupon = "UPDATE cupones SET Cantidad_Reservas = 0, Cantidad_Faltas = 0, Ultima_Fecha = NULL, Descuento = 0 WHERE ID_Cupon = {$cupon['ID_Cupon']}";
mysqli_query($conexion, $sqlResetCupon);
}
}
if ($maxFaltas > 0 && $cantidadFaltas > $maxFaltas) {
$cantidadReservas = 0;
$cantidadFaltas = 0;
$ultimaFecha = null;
$sqlResetCupon = "UPDATE cupones SET Cantidad_Reservas = 0, Cantidad_Faltas = 0, Ultima_Fecha = NULL, Descuento = 0 WHERE ID_Cupon = {$cupon['ID_Cupon']}";
mysqli_query($conexion, $sqlResetCupon);
}
}
$aplicarDescuento = false;
$reservasRestantes = null;
if ($umbral > 0) {
if (($cantidadReservas + 1) >= $umbral) {
$aplicarDescuento = true;
$reservasRestantes = 0;
} else {
$reservasRestantes = $umbral - $cantidadReservas - 1;
}
}
echo json_encode([
'success' => true,
'clienteEncontrado' => true,
'cantidadReservas' => $cantidadReservas,
'cantidadFaltas' => $cantidadFaltas,
'umbral' => $umbral,
'descuentoCanchas' => $descuentoCanchas,
'duracionCupon' => $duracionCupon,
'ultimaFecha' => $ultimaFecha,
'aplicarDescuento' => $aplicarDescuento,
'reservasRestantes' => $reservasRestantes,
'vencido' => $vencido
]);
+83
View File
@@ -0,0 +1,83 @@
<?php
require_once 'conexion.php';
header('Content-Type: application/json');
$fecha = isset($_GET['fecha']) ? $_GET['fecha'] : '';
$horario_inicio = isset($_GET['horario']) ? $_GET['horario'] : '';
$duracion = isset($_GET['duracion']) ? $_GET['duracion'] : 60; // duracion en minutos
$tipo = isset($_GET['tipo']) ? $_GET['tipo'] : ''; // 'F' para futbol, 'P' para padel
if (empty($fecha) || empty($horario_inicio) || empty($tipo)) {
echo json_encode([
'success' => false,
'message' => 'Parámetros incompletos'
]);
exit;
}
try {
// Obtener la cantidad total de canchas del tipo especificado y su duración
$t = mysqli_real_escape_string($conexion, $tipo);
$sqlCanchas = "SELECT Cant_Canchas as cantidad_canchas, Duracion as duracion_cancha
FROM canchas
WHERE Tipo = '$t'";
$resCanchas = mysqli_query($conexion, $sqlCanchas);
if (!$resCanchas) {
throw new Exception("Error al obtener información de canchas: " . mysqli_error($conexion));
}
$cancha = mysqli_fetch_assoc($resCanchas);
$cantidadCanchas = $cancha['cantidad_canchas'];
$duracionCancha = $cancha['duracion_cancha'];
// Convertir horario a minutos para comparación
$horaInicioArr = explode(':', $horario_inicio);
$horaInicioMin = intval($horaInicioArr[0]) * 60 + intval($horaInicioArr[1]);
$horaFinMin = $horaInicioMin + intval($duracion);
// Convertir a formato HH:MM:SS para la query
$horaInicio = $horario_inicio . ':00';
$horaFin = sprintf("%02d:%02d", intval($horaFinMin / 60), intval($horaFinMin % 60)) . ':00';
// Obtener la cantidad de reservas que se superponen con el horario seleccionado
$f = mysqli_real_escape_string($conexion, $fecha);
$sqlReservas = "SELECT COUNT(*) as reservas_solapadas
FROM reservas r
INNER JOIN canchas c ON r.ID_Cancha = c.ID_Cancha
WHERE c.Tipo = '$t'
AND DATE(r.Fecha_Hora) = '$f'
AND r.Estado != 2
AND (
(TIME(r.Fecha_Hora) < '$horaFin' AND ADDTIME(TIME(r.Fecha_Hora), SEC_TO_TIME($duracionCancha * 60)) > '$horaInicio')
)";
$resReservas = mysqli_query($conexion, $sqlReservas);
if (!$resReservas) {
throw new Exception("Error al contar reservas: " . mysqli_error($conexion));
}
$reservas = mysqli_fetch_assoc($resReservas);
$reservasSolapadas = $reservas['reservas_solapadas'];
// Calcular disponibilidad
$disponibles = $cantidadCanchas - $reservasSolapadas;
echo json_encode([
'success' => true,
'cantidad_total' => $cantidadCanchas,
'reservas' => $reservasSolapadas,
'disponibles' => max(0, $disponibles),
'horario' => $horaInicio,
'tipo' => $tipo
]);
} catch (Exception $e) {
echo json_encode([
'success' => false,
'message' => $e->getMessage()
]);
}
?>
+64
View File
@@ -0,0 +1,64 @@
<?php
require_once 'conexion.php';
header('Content-Type: application/json');
$fecha = isset($_GET['fecha']) ? $_GET['fecha'] : '';
if (empty($fecha)) {
echo json_encode([
'success' => false,
'message' => 'Fecha no proporcionada'
]);
exit;
}
try {
// Obtener la cantidad total de quinchos disponibles
$sqlCanchas = "SELECT Cant_Canchas as cantidad_quinchos
FROM canchas
WHERE Tipo = 'Q'";
$resCanchas = mysqli_query($conexion, $sqlCanchas);
if (!$resCanchas) {
throw new Exception("Error al obtener información del quincho: " . mysqli_error($conexion));
}
$cancha = mysqli_fetch_assoc($resCanchas);
$cantidadQuinchos = $cancha['cantidad_quinchos'];
// Obtener la cantidad de reservas de quincho para esa fecha
$f = mysqli_real_escape_string($conexion, $fecha);
$sqlReservas = "SELECT COUNT(*) as reservas_quincho
FROM reservas r
INNER JOIN canchas c ON r.ID_Cancha = c.ID_Cancha
WHERE c.Tipo = 'Q'
AND DATE(r.Fecha_Hora) = '$f'
AND r.Estado != 2";
$resReservas = mysqli_query($conexion, $sqlReservas);
if (!$resReservas) {
throw new Exception("Error al contar reservas: " . mysqli_error($conexion));
}
$reservas = mysqli_fetch_assoc($resReservas);
$reservasQuincho = $reservas['reservas_quincho'];
// Calcular disponibilidad
$disponibles = $cantidadQuinchos - $reservasQuincho;
echo json_encode([
'success' => true,
'cantidad_total' => $cantidadQuinchos,
'reservas' => $reservasQuincho,
'disponibles' => max(0, $disponibles)
]);
} catch (Exception $e) {
echo json_encode([
'success' => false,
'message' => $e->getMessage()
]);
}
?>
+40
View File
@@ -0,0 +1,40 @@
<?php
require_once 'conexion.php';
header('Content-Type: application/json');
try {
// Obtener columnas dinámicas (excluyendo ID_Gasto, Periodo_Desde, Periodo_Hasta)
$sql_columns = "SHOW COLUMNS FROM gastos";
$result_columns = $conexion->query($sql_columns);
$columnas = [];
while ($row = $result_columns->fetch_assoc()) {
$col = $row['Field'];
if (!in_array($col, ['ID_Gasto', 'Periodo_Desde', 'Periodo_Hasta'])) {
$columnas[] = $col;
}
}
// Obtener el registro actual (donde Periodo_Hasta IS NULL)
$sql_actual = "SELECT * FROM gastos WHERE Periodo_Hasta IS NULL ORDER BY Periodo_Desde DESC LIMIT 1";
$result_actual = $conexion->query($sql_actual);
$gasto_actual = null;
if ($result_actual && $result_actual->num_rows > 0) {
$gasto_actual = $result_actual->fetch_assoc();
}
echo json_encode([
'success' => true,
'columnas' => $columnas,
'gasto' => $gasto_actual,
'message' => $gasto_actual ? 'Datos cargados' : 'No hay gastos registrados'
]);
} catch (Exception $e) {
echo json_encode([
'success' => false,
'message' => $e->getMessage()
]);
}
?>
+7
View File
@@ -0,0 +1,7 @@
<?php
include 'conexion.php';
$res = mysqli_query($conexion, "SELECT * FROM horarios");
$horarios = mysqli_fetch_all($res, MYSQLI_ASSOC);
header('Content-Type: application/json');
echo json_encode($horarios);
?>
+26
View File
@@ -0,0 +1,26 @@
<?php
header('Content-Type: application/json');
require_once 'conexion.php';
if ($conexion->connect_error) {
echo json_encode([]);
exit;
}
$sql = "SELECT oc.ID_Orden, DATE(oc.Fecha) AS Fecha, oc.ID_Proveedor, p.Nombre AS Proveedor, p.Telefono, oc.Estado
FROM ordenes_compra oc
LEFT JOIN proveedores p ON oc.ID_Proveedor = p.ID_Proveedor
ORDER BY oc.Fecha DESC";
$result = $conexion->query($sql);
$ordenes = [];
if ($result) {
while ($fila = $result->fetch_assoc()) {
$ordenes[] = $fila;
}
}
echo json_encode($ordenes);
$conexion->close();
?>
+33
View File
@@ -0,0 +1,33 @@
<?php
require_once 'conexion.php';
// Verificar si la columna Estado existe
$checkColumn = $conexion->query("SHOW COLUMNS FROM productos WHERE Field='Estado'");
$columnaExists = $checkColumn && $checkColumn->num_rows > 0;
if ($columnaExists) {
// Solo mostrar productos activos
$result = $conexion->query("SELECT ID_Producto, Descripcion, Precio_Venta, Precio_Compra, Stock_Disponible FROM productos WHERE Estado = 1 ORDER BY ID_Producto DESC");
} else {
// Fallback: verificar si la columna Activo existe
$checkColumnActivo = $conexion->query("SHOW COLUMNS FROM productos WHERE Field='Activo'");
$activoExists = $checkColumnActivo && $checkColumnActivo->num_rows > 0;
if ($activoExists) {
$result = $conexion->query("SELECT ID_Producto, Descripcion, Precio_Venta, Precio_Compra, Stock_Disponible FROM productos WHERE Activo = 1 ORDER BY ID_Producto DESC");
} else {
$result = $conexion->query("SELECT ID_Producto, Descripcion, Precio_Venta, Precio_Compra, Stock_Disponible FROM productos ORDER BY ID_Producto DESC");
}
}
if (!$result) {
echo json_encode([]);
exit;
}
$productos = [];
while ($row = $result->fetch_assoc()) {
$productos[] = $row;
}
echo json_encode($productos);
?>
+34
View File
@@ -0,0 +1,34 @@
<?php
header('Content-Type: application/json');
require_once 'conexion.php';
if ($conexion->connect_error) {
echo json_encode([]);
exit;
}
$id_orden = isset($_GET['id']) ? intval($_GET['id']) : 0;
if ($id_orden <= 0) {
echo json_encode([]);
exit;
}
$sql = "SELECT op.ID_Producto, op.Cantidad, p.Descripcion
FROM ordenes_productos op
INNER JOIN productos p ON op.ID_Producto = p.ID_Producto
WHERE op.ID_Orden = ?";
$stmt = $conexion->prepare($sql);
$stmt->bind_param("i", $id_orden);
$stmt->execute();
$result = $stmt->get_result();
$productos = [];
while ($fila = $result->fetch_assoc()) {
$productos[] = $fila;
}
echo json_encode($productos);
$conexion->close();
?>
+23
View File
@@ -0,0 +1,23 @@
<?php
header('Content-Type: application/json');
require_once 'conexion.php';
$idProveedor = $_GET['id'] ?? 0;
$stmt = $conexion->prepare("
SELECT p.ID_Producto, p.Descripcion
FROM productos p
INNER JOIN proveedores_productos pp ON p.ID_Producto = pp.ID_Producto
WHERE pp.ID_Proveedor = ?
");
$stmt->bind_param("i", $idProveedor);
$stmt->execute();
$resultado = $stmt->get_result();
$productos = [];
while ($fila = $resultado->fetch_assoc()) {
$productos[] = $fila;
}
echo json_encode($productos);
+20
View File
@@ -0,0 +1,20 @@
<?php
header('Content-Type: application/json');
require_once 'conexion.php';
if ($conexion->connect_error) {
echo json_encode([]);
exit;
}
$resultado = $conexion->query("SELECT ID_Proveedor, Nombre, Telefono FROM proveedores");
$proveedores = [];
while ($fila = $resultado->fetch_assoc()) {
$proveedores[] = $fila;
}
echo json_encode($proveedores);
$conexion->close();
?>
File diff suppressed because it is too large Load Diff
+62
View File
@@ -0,0 +1,62 @@
<?php
require_once 'conexion.php';
header('Content-Type: application/json');
$fecha = isset($_GET['fecha']) ? $_GET['fecha'] : '';
$nombre = isset($_GET['nombre']) ? $_GET['nombre'] : '';
$dni = isset($_GET['dni']) ? $_GET['dni'] : '';
$tipo = isset($_GET['tipo']) ? $_GET['tipo'] : '';
$sql = "SELECT r.ID_Reserva, c.Nombre, c.DNI, c.Telefono, r.Fecha_Hora, ca.Tipo, IFNULL(r.Descuento, 0) as Descuento_Cupon, r.Monto, r.Numero, r.Estado
FROM reservas r
INNER JOIN clientes c ON r.ID_Cliente = c.ID_Cliente
LEFT JOIN canchas ca ON r.ID_Cancha = ca.ID_Cancha
WHERE 1=1";
//Filtro de Fecha
if (!empty($fecha)) {
$f = mysqli_real_escape_string($conexion, $fecha);
$sql .= " AND DATE(r.Fecha_Hora) = '$f'";
}
//Filtro de Nombre
if (!empty($nombre)) {
$n = mysqli_real_escape_string($conexion, $nombre);
$sql .= " AND c.Nombre LIKE '%$n%'";
}
// Filtro de DNI
if (!empty($dni)) {
$d = mysqli_real_escape_string($conexion, $dni);
$sql .= " AND c.DNI LIKE '%$d%'";
}
//Filtro de Tipo
if (!empty($tipo)) {
if ($tipo === 'futbol') {
$sql .= " AND ca.Tipo = 'F'";
} elseif ($tipo === 'padel') {
$sql .= " AND ca.Tipo = 'P'";
} elseif ($tipo === 'quincho') {
$sql .= " AND ca.Tipo = 'Q'";
}
}
$sql .= " ORDER BY r.Fecha_Hora DESC";
$resultado = mysqli_query($conexion, $sql);
$reservas = [];
if (!$resultado) {
die(json_encode(["error" => mysqli_error($conexion)]));
}
if ($resultado) {
while ($fila = mysqli_fetch_assoc($resultado)) {
$reservas[] = $fila;
}
}
header('Content-Type: application/json');
echo json_encode($reservas);
?>
+23
View File
@@ -0,0 +1,23 @@
<?php
session_start();
require_once 'conexion.php';
// Respuesta por defecto
header('Content-Type: application/json');
// Obtener todos los usuarios
$query = "SELECT ID_Usuario, Usuario, Rol, Nombre, Apellido, DNI, Correo, Telefono FROM usuarios ORDER BY Nombre ASC";
$result = $conexion->query($query);
if ($result) {
$usuarios = [];
while ($row = $result->fetch_assoc()) {
$usuarios[] = $row;
}
echo json_encode(['success' => true, 'usuarios' => $usuarios]);
} else {
echo json_encode(['success' => false, 'message' => 'Error al obtener usuarios: ' . $conexion->error]);
}
$conexion->close();
?>
+114
View File
@@ -0,0 +1,114 @@
<?php
require_once 'conexion.php';
$start = isset($_GET['start']) ? $_GET['start'] : null;
$end = isset($_GET['end']) ? $_GET['end'] : null;
$id_venta = isset($_GET['id_venta']) ? intval($_GET['id_venta']) : null;
$days = isset($_GET['days']) ? intval($_GET['days']) : null;
// Si se solicita una venta específica, devolver sus productos
if ($id_venta !== null) {
$stmt = $conexion->prepare("
SELECT
vp.ID_Producto,
p.Descripcion as nombre,
vp.Cantidad,
COALESCE(p.Precio_Venta, 0) as precio_unitario,
(vp.Cantidad * COALESCE(p.Precio_Venta, 0)) as subtotal
FROM ventas_productos vp
LEFT JOIN productos p ON vp.ID_Producto = p.ID_Producto
WHERE vp.ID_Venta = ?
ORDER BY vp.ID_Producto
");
if (!$stmt) {
http_response_code(500);
echo json_encode(['error' => 'Error en la consulta preparada: ' . $conexion->error]);
exit;
}
$stmt->bind_param("i", $id_venta);
$stmt->execute();
if ($stmt->error) {
http_response_code(500);
echo json_encode(['error' => 'Error al ejecutar: ' . $stmt->error]);
exit;
}
$result = $stmt->get_result();
$productos = [];
while ($row = $result->fetch_assoc()) {
$productos[] = [
'ID_Producto' => $row['ID_Producto'],
'nombre' => $row['nombre'],
'cantidad' => intval($row['Cantidad']),
'precio_unitario' => floatval($row['precio_unitario']),
'subtotal' => floatval($row['subtotal'])
];
}
header('Content-Type: application/json');
echo json_encode($productos);
$stmt->close();
exit;
}
// De lo contrario, devolver las ventas individuales del período
if ($days !== null) {
$end = date('Y-m-d');
$start = date('Y-m-d', strtotime("-{$days} days", strtotime($end)));
} else {
if (!$start && !$end) {
$start = date('Y-m-d');
$end = $start;
} elseif ($start && !$end) {
$end = $start;
} elseif (!$start && $end) {
$start = $end;
}
}
$startDateTime = $start . ' 00:00:00';
$endDateTime = $end . ' 23:59:59';
$stmt = $conexion->prepare("
SELECT ID_Venta, Fecha, Monto
FROM ventas
WHERE Fecha BETWEEN ? AND ?
ORDER BY Fecha DESC
");
if (!$stmt) {
http_response_code(500);
echo json_encode(['error' => 'Error en la consulta preparada: ' . $conexion->error]);
exit;
}
$stmt->bind_param("ss", $startDateTime, $endDateTime);
$stmt->execute();
if ($stmt->error) {
http_response_code(500);
echo json_encode(['error' => 'Error al ejecutar: ' . $stmt->error]);
exit;
}
$result = $stmt->get_result();
$ventas = [];
while ($row = $result->fetch_assoc()) {
$ventas[] = [
'ID_Venta' => intval($row['ID_Venta']),
'fecha_hora' => $row['Fecha'],
'monto_total' => floatval($row['Monto'])
];
}
$stmt->close();
header('Content-Type: application/json');
echo json_encode($ventas);
?>
+74
View File
@@ -0,0 +1,74 @@
<?php
error_reporting(E_ALL);
ini_set('display_errors', 0);
header('Content-Type: application/json');
try {
require_once 'conexion.php';
require_once 'config_mail.php';
$data = json_decode(file_get_contents('php://input'), true);
if (!isset($data['correo']) || empty($data['correo'])) {
echo json_encode(['success' => false, 'message' => 'Por favor ingresa un correo']);
exit;
}
$correo = mysqli_real_escape_string($conexion, trim($data['correo']));
// Verificar si el correo existe en la base de datos
$sql = "SELECT ID_Usuario, Usuario, Nombre FROM usuarios WHERE Correo = '$correo'";
$resultado = mysqli_query($conexion, $sql);
if (!$resultado) {
throw new Exception('Error en la consulta: ' . mysqli_error($conexion));
}
if (mysqli_num_rows($resultado) === 0) {
echo json_encode(['success' => false, 'message' => 'El correo no está registrado en el sistema']);
exit;
}
$usuario = mysqli_fetch_assoc($resultado);
$id_usuario = $usuario['ID_Usuario'];
$nombre_usuario = $usuario['Nombre'];
// Generar código de 6 dígitos
$codigo = str_pad(rand(0, 999999), 6, '0', STR_PAD_LEFT);
// Guardar el código con fecha de expiración (15 minutos)
$fecha_expiracion = date('Y-m-d H:i:s', strtotime('+15 minutes'));
$sql_update = "UPDATE usuarios SET Codigo_Recuperacion = '$codigo', Fecha_Exp_Codigo = '$fecha_expiracion' WHERE ID_Usuario = $id_usuario";
if (!mysqli_query($conexion, $sql_update)) {
throw new Exception('Error al actualizar: ' . mysqli_error($conexion));
}
// Construir el mensaje de email
$asunto = 'Código de Recuperación - Complejo Cap1tan';
$mensaje = "Hola $nombre_usuario,\n\n";
$mensaje .= "Hemos recibido una solicitud para recuperar tu contraseña en Complejo Cap1tan.\n\n";
$mensaje .= "Tu código de verificación es: " . $codigo . "\n\n";
$mensaje .= "Este código expira en 15 minutos.\n\n";
$mensaje .= "Si no realizaste esta solicitud, por favor ignora este correo.\n\n";
$mensaje .= "Saludos,\nEquipo de Complejo Cap1tan";
// Enviar email usando Brevo
$correo_enviado = enviarEmailBrevo($correo, $asunto, $mensaje, false);
// Respuesta exitosa (el código se guardó en la BD de todas formas)
echo json_encode([
'success' => true,
'message' => 'Se ha enviado un código de verificación a tu correo. Por favor revisa tu bandeja de entrada.',
'test_codigo' => $codigo // Cambiar a false en producción
]);
} catch (Exception $e) {
echo json_encode([
'success' => false,
'message' => 'Error: ' . $e->getMessage()
]);
}
?>
+93
View File
@@ -0,0 +1,93 @@
<?php
error_reporting(E_ALL);
ini_set('display_errors', 0);
header('Content-Type: application/json');
try {
require_once 'conexion.php';
$data = json_decode(file_get_contents('php://input'), true);
if (!isset($data['correo']) || !isset($data['codigo']) || !isset($data['nueva_contrasena'])) {
echo json_encode(['success' => false, 'message' => 'Faltan datos requeridos']);
exit;
}
$correo = mysqli_real_escape_string($conexion, trim($data['correo']));
$codigo = mysqli_real_escape_string($conexion, trim($data['codigo']));
$nueva_contrasena = mysqli_real_escape_string($conexion, $data['nueva_contrasena']);
// Validar que la contraseña tenga al menos 6 caracteres
if (strlen($nueva_contrasena) < 6) {
echo json_encode(['success' => false, 'message' => 'La contraseña debe tener al menos 6 caracteres']);
exit;
}
// Verificar el código y que no haya expirado
$sql = "SELECT ID_Usuario, Codigo_Recuperacion, Fecha_Exp_Codigo FROM usuarios WHERE Correo = '$correo'";
$resultado = mysqli_query($conexion, $sql);
if (!$resultado) {
error_log('Error en SELECT: ' . mysqli_error($conexion));
throw new Exception('Error en la consulta: ' . mysqli_error($conexion));
}
if (mysqli_num_rows($resultado) === 0) {
echo json_encode(['success' => false, 'message' => 'Correo no encontrado']);
exit;
}
$usuario = mysqli_fetch_assoc($resultado);
$id_usuario = $usuario['ID_Usuario'];
// Verificar si el código es correcto
if ($usuario['Codigo_Recuperacion'] === null || $usuario['Codigo_Recuperacion'] === '') {
echo json_encode(['success' => false, 'message' => 'No hay código generado. Solicita uno nuevo']);
exit;
}
if ($usuario['Codigo_Recuperacion'] !== $codigo) {
echo json_encode(['success' => false, 'message' => 'Código incorrecto']);
exit;
}
// Verificar si el código ha expirado
if ($usuario['Fecha_Exp_Codigo'] === null) {
echo json_encode(['success' => false, 'message' => 'Error: fecha de expiración no registrada']);
exit;
}
$fecha_actual = new DateTime();
$fecha_exp = new DateTime($usuario['Fecha_Exp_Codigo']);
if ($fecha_actual > $fecha_exp) {
echo json_encode(['success' => false, 'message' => 'El código ha expirado. Solicita uno nuevo']);
exit;
}
// Actualizar la contraseña - IMPORTANTE: el nombre de la columna es "Contraseña" con acento
$sql_update = "UPDATE usuarios SET `Contraseña` = '$nueva_contrasena', `Codigo_Recuperacion` = NULL, `Fecha_Exp_Codigo` = NULL WHERE ID_Usuario = $id_usuario";
if (!mysqli_query($conexion, $sql_update)) {
error_log('Error en UPDATE: ' . mysqli_error($conexion) . ' | SQL: ' . $sql_update);
throw new Exception('Error al actualizar: ' . mysqli_error($conexion));
}
// Verificar que se actualizó correctamente
if (mysqli_affected_rows($conexion) === 0) {
error_log('Warning: UPDATE ejecutado pero no afectó filas');
echo json_encode(['success' => false, 'message' => 'No se pudo actualizar la contraseña']);
exit;
}
echo json_encode(['success' => true, 'message' => 'Contraseña actualizada correctamente']);
} catch (Exception $e) {
error_log('Exception en Recuperar_Contrasena_Verificar: ' . $e->getMessage());
echo json_encode([
'success' => false,
'message' => 'Error: ' . $e->getMessage()
]);
}
?>
+123
View File
@@ -0,0 +1,123 @@
<?php
require_once 'conexion.php';
header('Content-Type: application/json');
try {
$data = json_decode(file_get_contents('php://input'), true);
if (!isset($data['nuevo_gasto']) || !isset($data['monto'])) {
throw new Exception("Datos incompletos");
}
$nuevo_gasto = trim($data['nuevo_gasto']);
$monto = floatval($data['monto']);
// Validar nombre del gasto
if (empty($nuevo_gasto) || $monto < 0) {
throw new Exception("Datos inválidos");
}
// Convertir nombre a formato de columna (minúsculas, sin espacios, con guion bajo)
$nombre_columna = strtolower(str_replace(' ', '_', $nuevo_gasto));
// Validar que sea un nombre válido para columna SQL
if (!preg_match('/^[a-z_][a-z0-9_]*$/', $nombre_columna)) {
throw new Exception("Nombre de gasto inválido");
}
// Verificar si la columna ya existe (sin prepared statement porque SHOW COLUMNS no lo soporta bien)
$sql_check = "SHOW COLUMNS FROM gastos LIKE '" . $conexion->real_escape_string($nombre_columna) . "'";
$result_check = $conexion->query($sql_check);
if ($result_check === false) {
throw new Exception("Error verificando columna: " . $conexion->error);
}
if ($result_check->num_rows === 0) {
// Columna no existe, agregar con ALTER TABLE
$sql_alter = "ALTER TABLE gastos ADD COLUMN `$nombre_columna` DECIMAL(10,2) DEFAULT NULL";
if (!$conexion->query($sql_alter)) {
throw new Exception("Error al agregar columna: " . $conexion->error);
}
}
// Obtener el ID del registro anterior (donde Periodo_Hasta IS NULL)
$sql_get_id = "SELECT ID_Gasto FROM gastos WHERE Periodo_Hasta IS NULL ORDER BY Periodo_Desde DESC LIMIT 1";
$result_id = $conexion->query($sql_get_id);
$fecha_hoy = date('Y-m-d');
$id_anterior = null;
if ($result_id && $result_id->num_rows > 0) {
$row = $result_id->fetch_assoc();
$id_anterior = $row['ID_Gasto'];
// Cerrar el período anterior
$sql_update = "UPDATE gastos SET Periodo_Hasta = ? WHERE ID_Gasto = ?";
$stmt_update = $conexion->prepare($sql_update);
$stmt_update->bind_param('si', $fecha_hoy, $id_anterior);
if (!$stmt_update->execute()) {
throw new Exception("Error actualizando período anterior: " . $stmt_update->error);
}
$stmt_update->close();
// Obtener todos los valores del registro anterior para reutilizarlos
$sql_get_values = "SELECT * FROM gastos WHERE ID_Gasto = ?";
$stmt_get_values = $conexion->prepare($sql_get_values);
$stmt_get_values->bind_param('i', $id_anterior);
$stmt_get_values->execute();
$result_values = $stmt_get_values->get_result();
$valores_anteriores = $result_values->fetch_assoc();
$stmt_get_values->close();
}
// Construir INSERT dinámico
$columnas = ['Periodo_Desde', 'Periodo_Hasta', $nombre_columna];
$valores = [date('Y-m-d'), null, $monto];
$placeholders = ['?', '?', '?'];
$tipos = 'ssd';
// Si hay datos anteriores, agregar todas las columnas existentes
if (!empty($valores_anteriores)) {
foreach ($valores_anteriores as $col => $val) {
if (!in_array($col, ['ID_Gasto', 'Periodo_Desde', 'Periodo_Hasta', $nombre_columna])) {
$columnas[] = $col;
$valores[] = $val;
$placeholders[] = '?';
$tipos .= 'd';
}
}
}
$sql_insert = "INSERT INTO gastos (" . implode(', ', $columnas) . ") VALUES (" . implode(', ', $placeholders) . ")";
$stmt_insert = $conexion->prepare($sql_insert);
if (!$stmt_insert) {
throw new Exception("Error preparando INSERT: " . $conexion->error);
}
$stmt_insert->bind_param($tipos, ...$valores);
if (!$stmt_insert->execute()) {
throw new Exception("Error insertando registro: " . $stmt_insert->error);
}
$nuevo_id = $stmt_insert->insert_id;
$stmt_insert->close();
echo json_encode([
'success' => true,
'message' => 'Gasto agregado correctamente',
'id_gasto' => $nuevo_id
]);
} catch (Exception $e) {
echo json_encode([
'success' => false,
'message' => $e->getMessage()
]);
}
?>
+20
View File
@@ -0,0 +1,20 @@
<?php
$data = json_decode(file_get_contents("php://input"), true);
require_once 'conexion.php';
// Insertar orden
$stmt = $conexion->prepare("INSERT INTO ordenes_compra (Fecha, ID_Proveedor) VALUES (NOW(), ?)");
$stmt->bind_param("i", $data["proveedor"]);
$stmt->execute();
$idOrden = $stmt->insert_id;
// Insertar productos de la orden
foreach ($data["productos"] as $p) {
$stmt = $conexion->prepare("INSERT INTO ordenes_productos (ID_Orden, ID_Producto, Cantidad) VALUES (?, ?, ?)");
$stmt->bind_param("iii", $idOrden, $p["id"], $p["cantidad"]);
$stmt->execute();
}
echo "Orden registrada correctamente.";
?>
+34
View File
@@ -0,0 +1,34 @@
<?php
session_start();
require_once 'conexion.php';
$productos = json_decode(file_get_contents("php://input"), true);
// Calcular monto total
$monto = 0;
foreach ($productos as $p) {
$monto += $p['subtotal'];
}
// Obtener ID del usuario desde la sesión
$id_usuario = isset($_SESSION['id_usuario']) ? intval($_SESSION['id_usuario']) : null;
// Insertar venta
$stmt = $conexion->prepare("INSERT INTO ventas (Fecha, Monto, ID_Usuario) VALUES (NOW(), ?, ?)");
$stmt->bind_param("di", $monto, $id_usuario);
$stmt->execute();
$id_venta = $stmt->insert_id;
// Insertar productos vendidos
foreach ($productos as $p) {
$stmt = $conexion->prepare("INSERT INTO ventas_productos (ID_Venta, ID_Producto, Cantidad) VALUES (?, ?, ?)");
$stmt->bind_param("iii", $id_venta, $p['id'], $p['cantidad']);
$stmt->execute();
// Descontar stock
//$stmt = $conexion->prepare("UPDATE productos SET Stock_Disponible = Stock_Disponible - ? WHERE ID_Producto = ?");
//$stmt->bind_param("ii", $p['cantidad'], $p['id']);
//$stmt->execute();
}
echo "Venta registrada correctamente.";
?>
+31
View File
@@ -0,0 +1,31 @@
<?php
require_once 'conexion.php';
if ($conexion->connect_error) {
die("Error de conexión: " . $conexion->connect_error);
}
$usuario = $_POST['usuario'];
$clave = $_POST['clave'];
$nombre = $_POST['nombre'];
$apellido = $_POST['apellido'];
$dni = $_POST['dni'];
$telefono = $_POST['telefono'];
$correo = $_POST['correo'];
$rol = $_POST['rol'];
$sql = "INSERT INTO usuarios (DNI, Usuario, Contraseña, Rol, Nombre, Apellido, Correo, Telefono)
VALUES (?, ?, ?, ?, ?, ?, ?, ?)";
$stmt = $conexion->prepare($sql);
$stmt->bind_param("isssssss", $dni, $usuario, $clave, $rol, $nombre, $apellido, $correo, $telefono);
if ($stmt->execute()) {
echo "Registro exitoso.";
} else {
echo "Error: " . $stmt->error;
}
$stmt->close();
$conexion->close();
?>
+27
View File
@@ -0,0 +1,27 @@
<?php
session_start();
header('Content-Type: application/json');
if (!isset($_SESSION['id_usuario'])) {
echo json_encode(['success' => false, 'message' => 'Sesión no iniciada']);
exit();
}
require_once 'conexion.php';
$id = intval($_SESSION['id_usuario']);
$query = "SELECT ID_Usuario, Usuario, Rol, Nombre, Apellido, DNI, Correo, Telefono FROM usuarios WHERE ID_Usuario = ?";
$stmt = $conexion->prepare($query);
$stmt->bind_param('i', $id);
$stmt->execute();
$result = $stmt->get_result();
if ($result && $row = $result->fetch_assoc()) {
echo json_encode(['success' => true, 'usuario' => $row]);
} else {
echo json_encode(['success' => false, 'message' => 'Usuario no encontrado']);
}
$stmt->close();
$conexion->close();
?>
+73
View File
@@ -0,0 +1,73 @@
<?php
header('Content-Type: application/json');
require_once 'conexion.php';
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
echo json_encode(['success' => false, 'error' => 'Método no permitido.']);
exit;
}
$idReserva = isset($_POST['id_reserva']) ? intval($_POST['id_reserva']) : 0;
if ($idReserva === 0 || !isset($_FILES['comprobante'])) {
echo json_encode(['success' => false, 'error' => 'Faltan datos obligatorios.']);
exit;
}
$file = $_FILES['comprobante'];
$ext = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION));
$allowed = ['jpg', 'jpeg', 'png'];
// Validar extensión
if (!in_array($ext, $allowed)) {
echo json_encode(['success' => false, 'error' => 'Formato no permitido. Solo JPG, JPEG o PNG.']);
exit;
}
// Definir rutas
$nombreArchivo = "reserva_" . $idReserva . "_" . time() . "." . $ext;
$carpetaDestino = "C:\\xampp\\htdocs\\TP-Taller\\ProyectoTaller\\uploads\\comprobantes\\";
$rutaCompleta = $carpetaDestino . $nombreArchivo;
// Mover el archivo al servidor
if (move_uploaded_file($file['tmp_name'], $rutaCompleta)) {
// Actualizar la base de datos con el nombre del archivo
$stmt = $conexion->prepare("UPDATE reservas SET Comprobante = ? WHERE ID_Reserva = ?");
$stmt->bind_param('si', $nombreArchivo, $idReserva);
$stmt->execute();
if ($stmt->affected_rows > 0) {
// --- NOTIFICACIÓN AL ADMINISTRADOR DE CANCHAS ---
// 1. Buscamos el teléfono del usuario con rol 'cancha'
$resUser = $conexion->query("SELECT Telefono FROM usuarios WHERE Rol = 'cancha' LIMIT 1");
if ($resUser && $resUser->num_rows > 0) {
$admin = $resUser->fetch_assoc();
$telefonoAdmin = $admin['Telefono']; // Ej: "549343..."
// 2. Limpiamos el formato del teléfono del administrador
$telefonoLimpio = preg_replace('/[^0-9]/', '', $telefonoAdmin);
// 3. Armamos el mensaje con un link directo para que el admin vea la foto desde su celular
// Nota: Cuando pases el sistema a producción, reemplaza 'localhost' por tu IP pública o dominio
$urlFoto = "http://localhost/TP-Taller/ProyectoTaller/uploads/comprobantes/" . $nombreArchivo;
$mensaje = "Alerta: Se ha subido un comprobante para la Reserva #$idReserva. Ver foto aquí: $urlFoto";
// 4. Llamamos al bot de Python de forma asíncrona para no trabar la pantalla del cliente
$scriptPython = "C:\\xampp\\htdocs\\TP-Taller\\ProyectoTaller\\python\\Enviar_WSP.py";
$comando = "start /B python \"$scriptPython\" $telefonoLimpio \"$mensaje\"";
pclose(popen($comando, "r"));
}
echo json_encode(['success' => true, 'message' => 'Comprobante subido y administrador notificado.']);
} else {
echo json_encode(['success' => false, 'error' => 'No se encontró la reserva para actualizar.']);
}
$stmt->close();
} else {
echo json_encode(['success' => false, 'error' => 'No se pudo guardar el archivo en el servidor.']);
}
$conexion->close();
?>
+109
View File
@@ -0,0 +1,109 @@
<?php
set_time_limit(0);
require_once 'conexion.php';
// Rutas base de tu proyecto
$rutaProyecto = "C:\\xampp\\htdocs\\TP-Taller\\ProyectoTaller\\";
$carpetaDestino = $rutaProyecto . "backups\\";
$mysqldump = "C:\\xampp\\mysql\\bin\\mysqldump.exe";
$diasDeRetencion = 30;
// --- GENERACIÓN DEL BACKUP SQL ---
$fecha = date('Y-m-d_H-i-s');
$nombreArchivoSql = "bd_cap1tan_" . $fecha . ".sql";
$rutaSql = $carpetaDestino . $nombreArchivoSql;
$comando = "$mysqldump -h $host -u $user $db > \"$rutaSql\" 2>&1";
exec($comando, $salida, $resultado);
if ($resultado !== 0) {
echo "<h2 style='color: red;'>Error al generar la base de datos. Abortando.</h2>";
exit;
}
// --- EMPAQUETADO ZIP ---
$nombreArchivoZip = "backup_completo_" . $fecha . ".zip";
$rutaZip = $carpetaDestino . $nombreArchivoZip;
$zip = new ZipArchive();
if ($zip->open($rutaZip, ZipArchive::CREATE) === TRUE) {
// Guardamos la base de datos dentro del ZIP
$zip->addFile($rutaSql, $nombreArchivoSql);
// Guardamos el archivo de conexión
$rutaConexion = $rutaProyecto . "php\\conexion.php";
if (file_exists($rutaConexion)) {
$zip->addFile($rutaConexion, "php/conexion.php");
}
// Guardamos el bot de Python
$rutaBot = $rutaProyecto . "python\\Enviar_WSP.py";
if (file_exists($rutaBot)) {
$zip->addFile($rutaBot, "python/Enviar_WSP.py");
}
// Guardamos la carpeta uploads completa
$rutaUploads = $rutaProyecto . "uploads\\";
// Verificamos si la carpeta existe antes de intentar abrirla
if (is_dir($rutaUploads)) {
// El sabueso que busca todos los archivos dentro de la carpeta
$archivos = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($rutaUploads),
RecursiveIteratorIterator::LEAVES_ONLY
);
foreach ($archivos as $nombre => $archivo) {
// Saltamos las carpetas vacías o los directorios del sistema (. y ..)
if (!$archivo->isDir()) {
// Obtenemos la ruta real del archivo en Windows
$rutaReal = $archivo->getRealPath();
// Calculamos la ruta relativa para que adentro del ZIP quede ordenado en "uploads/comprobantes/foto.jpg"
$rutaRelativa = "uploads/" . substr($rutaReal, strlen($rutaUploads));
// Reemplazamos las barras invertidas de Windows por barras normales para el ZIP
$rutaRelativa = str_replace('\\', '/', $rutaRelativa);
// Añadimos el archivo al ZIP
$zip->addFile($rutaReal, $rutaRelativa);
}
}
}
$zip->close();
// Borramos el archivo .sql suelto
unlink($rutaSql);
echo "<h2 style='color: green;'>¡Éxito! Backup COMPLETO generado correctamente.</h2>";
echo "<p>Ruta: <b>" . $rutaZip . "</b></p>";
} else {
echo "<h2 style='color: red;'>Error al intentar crear el archivo ZIP.</h2>";
}
// --- AUTO-LIMPIEZA DE BACKUPS VIEJOS ---
$archivosZip = glob($carpetaDestino . "*.zip");
$fechaActual = time();
$borrados = 0;
foreach ($archivosZip as $archivo) {
if (is_file($archivo)) {
$diasDeAntiguedad = ($fechaActual - filemtime($archivo)) / (60 * 60 * 24);
if ($diasDeAntiguedad >= $diasDeRetencion) {
unlink($archivo);
$borrados++;
}
}
}
echo "<hr>";
if ($borrados > 0) {
echo "<p>Limpieza completada: Se eliminaron $borrados backup(s) viejo(s).</p>";
} else {
echo "<p>Mantenimiento al día: Ningún backup supera los $diasDeRetencion días.</p>";
}
?>
+13
View File
@@ -0,0 +1,13 @@
<?php
$host = 'localhost';
$user = 'root';
$password = 'admin';
$db = 'complejo_cap1tan';
$conexion = new mysqli($host, $user, $password, $db);
if ($conexion->connect_error) {
die('Error de conexión: ' . $conexion->connect_error);
}
$conexion->set_charset('utf8');
?>
+90
View File
@@ -0,0 +1,90 @@
<?php
/**
* Configuración de Brevo SMTP
* Este archivo contiene las credenciales para enviar emails vía Brevo
*/
// Credenciales de Brevo
define('BREVO_API_KEY', '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');
define('BREVO_API_URL', 'https://api.brevo.com/v3/smtp/email');
define('BREVO_FROM_EMAIL', 'lumicaela2.987@gmail.com');
define('BREVO_FROM_NAME', 'Complejo Cap1tan');
/**
* Función para enviar emails usando API REST de Brevo
* Esta es más confiable que SMTP directo
*/
function enviarEmailBrevo($para, $asunto, $mensaje, $esHTML = false) {
try {
// Preparar el payload
$payload = [
'sender' => [
'name' => BREVO_FROM_NAME,
'email' => BREVO_FROM_EMAIL
],
'to' => [
[
'email' => $para,
'name' => $para
]
],
'subject' => $asunto,
'htmlContent' => $esHTML ? $mensaje : nl2br(htmlspecialchars($mensaje)),
'textContent' => $mensaje
];
// Preparar headers
$headers = [
'Content-Type: application/json',
'api-key: ' . BREVO_API_KEY,
'Accept: application/json'
];
// Inicializar cURL
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, BREVO_API_URL);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
// Ejecutar
$respuesta = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$error = curl_error($ch);
curl_close($ch);
// Verificar respuesta
if ($error) {
error_log('Brevo API Error: ' . $error);
return false;
}
if ($http_code >= 200 && $http_code < 300) {
error_log('Email enviado exitosamente a ' . $para);
return true;
} else {
error_log('Brevo API HTTP ' . $http_code . ': ' . $respuesta);
return false;
}
} catch (Exception $e) {
error_log('Brevo Exception: ' . $e->getMessage());
return false;
}
}
/**
* Función fallback usando mail() nativa
*/
function enviarEmailFallback($para, $asunto, $mensaje) {
$headers = "From: " . BREVO_FROM_NAME . " <" . BREVO_FROM_EMAIL . ">\r\n";
$headers .= "Reply-To: " . BREVO_FROM_EMAIL . "\r\n";
$headers .= "Content-Type: text/plain; charset=UTF-8\r\n";
return @mail($para, $asunto, $mensaje, $headers);
}
?>