Carpeta controllers

This commit is contained in:
Axel Axt
2026-08-04 19:20:18 -03:00
parent f13321f90c
commit 24ae0e327f
14 changed files with 6971 additions and 0 deletions
+541
View File
@@ -0,0 +1,541 @@
<?php
// Validacion de token
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
if (!isset($_POST['csrf_token']) || !hash_equals($_SESSION['csrf_token'], $_POST['csrf_token'])) { // Recorre todos los caracteres (siempre) y retorna true or false
$_SESSION['flash_error'] = 'Acción inválida.';
header('Location: index.php?opt=inicio_operador');
exit;
}
}
// Requiere el modelo de producto
require_once __DIR__ . '/../models/productoModel.php';
$productomodel = new productoModel;
// Validar sesón
if (!isset($_SESSION['user'])) {
header("Location: index.php?opt=login_operador");
exit;
}
$opt = $_GET['opt'] ?? null;
// Manejo de opciones $opt
switch($opt) {
// LISTAR PRODUCTOS
case 'productos':
// Utilizamos el modelo para obtener la lista completa de productos
$productos = $productomodel->listarProductos();
// Saneamiento de datos para enviar a la view
foreach ($productos as $i => $p) {
if (($p['precio'] === null) || ($p['precio'] == 0)) {
$productos[$i]['precio'] = '-';
} else {
$productos[$i]['precio'] = '$ ' . number_format($p['precio'], 2, '.', ',');
}
if ($p['stock'] === null || $p['stock'] === 0) {
$productos[$i]['stock'] = '-';
}
$productos[$i]['descuento_total'] = number_format($p['descuento_total'], 2, '.', '') . ' %';
}
ob_start();
require __DIR__ . '/../views/productos/listaProductosView.php';
return ob_get_clean();
// LISTAR PRODUCTOS INACTIVOS
case 'productos_inactivos':
// Utilizamos el modelo para obtener la lista completa de productos
$productos = $productomodel->listarProductosInactivos();
ob_start();
require __DIR__ . '/../views/productos/listaProductosInactivosView.php';
return ob_get_clean();
// CREAR PRODUCTO
case 'crear_producto':
// Mostramos la vista con los datos correspondientes
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
$categorias = $productomodel->listarCategorias();
$tipos = $productomodel->listarTipos();
ob_start();
require __DIR__ . '/../views/productos/crearProductoView.php';
return ob_get_clean();
}
// En caso de modificación de datos
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$marca = trim($_POST['marca'] ?? '');
$modelo = trim($_POST['modelo'] ?? '');
$id_categoria = trim($_POST['categoria'] ?? '');
$id_tipo = trim($_POST['tipo'] ?? '');
// Normalización de datos
$descuentoRaw = trim($_POST['descuento'] ?? '');
$descuento = $descuentoRaw === '' ? null : $descuentoRaw;
$errores = [];
// Validaciones
if ($marca === '') {
$errores[] = "La marca no puede estar vacía.";
} else if (!preg_match("/^[A-Za-zÁÉÍÓÚÑáéíóúñ0-9]+(?: [A-Za-zÁÉÍÓÚÑáéíóúñ0-9]+)*$/", $marca)) {
$errores[] = "La marca solo puede contener letras, números y espacios.";
} else if (strlen($marca) < 2) {
$errores[] = "La marca debe tener al menos 2 caracteres.";
} else if (strlen($marca) > 50) {
$errores[] = "La marca no puede superar los 50 caracteres.";
}
if ($modelo === '') {
$errores[] = "El modelo no puede estar vacío.";
} else if (!preg_match("/^[A-Za-zÁÉÍÓÚÑáéíóúñ0-9.\-]+(?: [A-Za-zÁÉÍÓÚÑáéíóúñ0-9.\-]+)*$/", $modelo)) {
$errores[] = "El modelo solo puede contener letras, números, espacios, guiones y puntos";
} else if (strlen($modelo) < 2) {
$errores[] = "El modelo debe tener al menos 2 caracteres.";
} else if (strlen($modelo) > 50) {
$errores[] = "El modelo no puede superar los 50 caracteres.";
}
if ($descuento !== null) {
if (!preg_match("/^\d{1,3}(\.\d{1,2})?$/", $descuento)) {
$errores[] = "El descuento debe ser un número válido con hasta 2 decimales.";
} else if ((float)$descuento <= 0 || (float)$descuento > 100) {
$errores[] = "El descuento debe estar entre 0 a 100.";
}
}
if ($id_categoria === '') {
$errores[] = "Debe seleccionar una categoría.";
} else if (!filter_var($id_categoria, FILTER_VALIDATE_INT) || $id_categoria <= 0) {
$errores[] = "La categoría seleccionada no es válida.";
} else if (!$productomodel->existeCategoria($id_categoria)) {
$errores[] = "La categoría ingresada no existe.";
}
if ($id_tipo === '') {
$errores[] = "Debe seleccionar un tipo.";
} else if (!filter_var($id_tipo, FILTER_VALIDATE_INT) || $id_tipo <= 0) {
$errores[] = "El tipo seleccionado no es válido.";
} else if (!$productomodel->existeTipo($id_tipo)) {
$errores[] = "El tipo ingresado no existe.";
}
if (($id_tipo === 2) && ($descuento !== null)) {
$errores[] = "No se permite descuento si el tipo de producto es Servicio.";
}
if (!empty($errores)) {
$_SESSION['flash_error'] = implode('<br>', $errores);
header("Location: index.php?opt=crear_producto");
exit;
}
// Utilizamos el método del modelo para crear el producto
if ($productomodel->crearProducto([
'marca' => $marca,
'modelo' => $modelo,
'precio' => null,
'stock' => null,
'descuento' => $descuento !== null ? (float)$descuento : null,
'id_categoria' => $id_categoria,
'id_tipo' => $id_tipo
])) {
$_SESSION['flash_success'] = "Producto creado correctamente.";
} else {
$_SESSION['flash_error'] = "No se pudo crear el producto.";
}
header("Location: index.php?opt=productos");
exit;
}
// EDITAR PRODUCTO
case 'editar_producto':
$idEditar = (int) ($_GET['id'] ?? 0);
if ($idEditar <= 0) {
header("Location: index.php?opt=productos");
exit;
}
// Busco el producto en la base de datos mediante el modelo
$producto = $productomodel->obtenerPorId($idEditar);
if (!$producto) {
$_SESSION['flash_error'] = "No se encontró el producto.";
header("Location: index.php?opt=productos");
exit;
};
// (Para indicar que aún no existen pedidos que incluyan dicho producto (no existe ID de pedido))
if ($producto['id_pedido'] === null) {
$producto['id_pedido'] = 'Aún no existe pedido que incluya este producto';
}
// Si el descuento es null lo seteamos en 0
if ($producto['descuento'] === null) {
$producto['descuento'] = 0;
}
// Mostrar datos de producto
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
$categorias = $productomodel->listarCategorias();
$tipos = $productomodel->listarTipos();
ob_start();
require __DIR__ . '/../views/productos/editarProductoView.php';
return ob_get_clean();
}
// Caso en donde se modifican los datos
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// Normalización de datos
$descuentoRaw = trim($_POST['descuento'] ?? '');
$descuento = $descuentoRaw === '' ? null : $descuentoRaw;
$errores = [];
// Validaciones
if ($descuento !== null) {
if (!preg_match("/^\d{1,3}(\.\d{1,2})?$/", $descuento)) {
$errores[] = "El descuento debe ser un número válido con hasta 2 decimales.";
} else if ((float)$descuento < 0 || (float)$descuento > 100) {
$errores[] = "El descuento debe estar entre 0 a 100.";
}
}
if (!empty($errores)) {
$_SESSION['flash_error'] = implode('<br>', $errores);
header("Location: index.php?opt=editar_producto&id=" . $idEditar);
exit;
}
// Recalculoamos precio (en caso de que se modifique descuento)
require_once __DIR__ . '/../models/pedidoModel.php';
$pedidomodel = new pedidoModel();
$costoUnitario = $pedidomodel->obtenerCosto($_GET['id']);
$categoria = $productomodel->obtenerPorIdCategoria($producto['id_categoria']);
// Antes de guardar los datos verificamos que la suma del descuento no sea mayor a 100
if (($categoria['porcentaje_ganancia'] + $descuento) > 100) {
$_SESSION['flash_error'] = "La suma entre el descuento ingresado y el descuento de la categoria supera el 100%. Verifique.";
header("Location:index.php?opt=editar_producto&id=$idEditar");
exit;
}
// Creamos el array con los datos correspondientes
$guardarData = [
'precio' => $costoUnitario !== null ? (100 + $categoria['porcentaje_ganancia']) * $costoUnitario / 100 : null,
'descuento' => $descuento !== null ? (float) $descuento : null,
'id_categoria' => $producto['id_categoria']
];
// Utilizamos la función del modelo para actualizar el producto
if ($productomodel->actualizarProducto($_GET['id'], $guardarData)) {
$_SESSION['flash_success'] = "Datos actualizados correctamente.";
} else {
$_SESSION['flash_error'] = "No se pudo actualizar los datos.";
}
header("Location: index.php?opt=productos");
exit;
}
// CAMBIAR ESTADO DEL PRODUCTO (ACTIVO / INACTIVO)
case 'cambiar_estado':
$idProducto = (int) ($_POST['id'] ?? 0);
$nuevoEstado = isset($_POST['estado']) ? (bool) $_POST['estado'] : null;
if ($idProducto <= 0 || !is_bool($nuevoEstado)) {
header("Location: index.php?opt=productos");
exit;
};
$productomodel->actualizarEstado($idProducto, $nuevoEstado);
$_SESSION['flash_success'] = "Estado actualizado correctamente.";
header("Location: index.php?opt=productos");
exit;
// LISTAR LAS CATEGORIAS DE PRODUCTOS
case 'categorias':
$categorias = $productomodel->listarCategorias();
foreach ($categorias as $i => $c) {
if (($categorias)[$i]['porcentaje_ganancia'] === null) {
$c['porcentaje_ganancia'] = 0;
}
if (($categorias)[$i]['descuento'] === null) {
$c['descuento'] = 0;
}
$categorias[$i]['porcentaje_ganancia'] = number_format($c['porcentaje_ganancia'], 2, '.', '') . ' %';
$categorias[$i]['descuento'] = number_format($c['descuento'], 2, '.', '') . ' %';
}
ob_start();
require __DIR__ . '/../views/productos/listaCategoriasView.php';
return ob_get_clean();
// CREAR NUEVA CATEGORIA DE PRODUCTOS
case 'crear_categoria':
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
ob_start();
require __DIR__ . '/../views/productos/crearCategoriaView.php';
return ob_get_clean();
}
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$nombre = trim($_POST['nombre'] ?? '');
// Normalización
$porcentaje_gananciaRaw = trim($_POST['porcentaje_ganancia'] ?? '');
$porcentaje_ganancia = $porcentaje_gananciaRaw === '' ? null : $porcentaje_gananciaRaw;
$descuentoRaw = trim($_POST['descuento'] ?? '');
$descuento = $descuentoRaw === '' ? null : $descuentoRaw;
$errores = [];
// Validaciones
if ($nombre === '') {
$errores[] = "El nombre no puede estar vacío.";
} else if (!preg_match("/^[A-Za-zÁÉÍÓÚÑáéíóúñ0-9]+(?: [A-Za-zÁÉÍÓÚÑáéíóúñ0-9]+)*$/", $nombre)) {
$errores[] = "El nombre solo puede contener letras, números y espacios.";
} else if (strlen($nombre) < 2) {
$errores[] = "El nombre debe tener al menos 2 caracteres.";
} else if (strlen($nombre) > 50) {
$errores[] = "El nombre no puede superar los 50 caracteres.";
}
if ($porcentaje_ganancia !== null) {
if (!preg_match("/^\d{1,3}(\.\d{1,2})?$/", $porcentaje_ganancia)) {
$errores[] = "La ganancia debe ser un número válido con hasta 2 decimales.";
} else if ((float)$porcentaje_ganancia <= 0 || (float)$porcentaje_ganancia > 100) {
$errores[] = "La ganancia debe estar entre 0 a 100.";
}
}
if ($descuento !== null) {
if (!preg_match("/^\d{1,3}(\.\d{1,2})?$/", $descuento)) {
$errores[] = "El descuento debe ser un número válido con hasta 2 decimales.";
} else if ((float)$descuento < 0 || (float)$descuento > 100) {
$errores[] = "El descuento debe estar entre 0 a 100.";
}
}
if (!empty($errores)) {
$_SESSION['flash_error'] = implode('<br>', $errores);
header("Location: index.php?opt=crear_categoria");
exit;
}
if ($productomodel->crearCategoria([
'nombre' => $nombre,
'porcentaje_ganancia' => $porcentaje_ganancia !== null ? (float) $porcentaje_ganancia : null,
'descuento' => $descuento !== null ? (float) $descuento : null
])) {
$_SESSION['flash_success'] = "Categoría creada correctamente.";
} else {
$_SESSION['flash_error'] = "No se pudo crear la categoría.";
}
header("Location: index.php?opt=categorias");
exit;
}
// EDITAR CATEGORIA
case 'editar_categoria':
$idEditar = (int) ($_GET['id'] ?? 0);
if ($idEditar <= 0) {
header("Location: index.php?opt=categorias");
exit;
}
// Busco la categoría en la base de datos mediante el modelo
$categorias = $productomodel->obtenerPorIdCategoria($idEditar);
if (!$categorias) {
header("Location: index.php?opt=categorias");
exit;
};
// Si el descuento o el porcentaje_ganancia es null lo seteamos en 0
if ($categorias['porcentaje_ganancia'] === null) {
$categorias['porcentaje_ganancia'] = 0;
}
if ($categorias['descuento'] === null) {
$categorias['descuento'] = 0;
}
// Mostrar datos de producto
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
ob_start();
require __DIR__ . '/../views/productos/editarCategoriaView.php';
return ob_get_clean();
}
// Caso en donde se modifican los datos
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$nombre = trim($_POST['nombre'] ?? '');
// Normalización
$porcentaje_gananciaRaw = trim($_POST['porcentaje_ganancia'] ?? '');
$porcentaje_ganancia = $porcentaje_gananciaRaw === '' ? null : $porcentaje_gananciaRaw;
$descuentoRaw = trim($_POST['descuento'] ?? '');
$descuento = $descuentoRaw === '' ? null : $descuentoRaw;
$errores = [];
// Validaciones
if ($nombre === '') {
$errores[] = "El nombre no puede estar vacío.";
} else if (!preg_match("/^[A-Za-zÁÉÍÓÚÑáéíóúñ0-9]+(?: [A-Za-zÁÉÍÓÚÑáéíóúñ0-9]+)*$/", $nombre)) {
$errores[] = "El nombre solo puede contener letras, números y espacios.";
} else if (strlen($nombre) < 2) {
$errores[] = "El nombre debe tener al menos 2 caracteres.";
} else if (strlen($nombre) > 50) {
$errores[] = "El nombre no puede superar los 50 caracteres.";
}
if ($porcentaje_ganancia !== null) {
if (!preg_match("/^\d{1,3}(\.\d{1,2})?$/", $porcentaje_ganancia)) {
$errores[] = "La ganancia debe ser un número válido con hasta 2 decimales.";
} else if ((float)$porcentaje_ganancia <= 0 || (float)$porcentaje_ganancia > 100) {
$errores[] = "La ganancia debe estar entre 0 a 100.";
}
}
if ($descuento !== null) {
if (!preg_match("/^\d{1,3}(\.\d{1,2})?$/", $descuento)) {
$errores[] = "El descuento debe ser un número válido con hasta 2 decimales.";
} else if ((float)$descuento < 0 || (float)$descuento > 100) {
$errores[] = "El descuento debe estar entre 0 a 100.";
}
}
if (!empty($errores)) {
$_SESSION['flash_error'] = implode('<br>', $errores);
header("Location: index.php?opt=editar_categoria&id=" . $idEditar);
exit;
}
// Verificamos que la suma entre los descuentos no supere el 100%
require_once __DIR__ . '/../models/productoModel.php';
$productomodel = new productoModel();
$productosDescuentos = $productomodel->obtenerDescuento($idEditar);
foreach ($productosDescuentos as $i => $p) {
if (($productosDescuentos[$i]['descuento'] + $descuento) > 100) {
$_SESSION['flash_error'] = "Existe al menos un producto que supera el 100% de sumatoria en el descuento. Verifique.";
header("Location:index.php?opt=editar_categoria&id=$idEditar");
exit;
}
}
$guardarData = [
'nombre' => $nombre,
'porcentaje_ganancia' => $porcentaje_ganancia !== null ? (float) $porcentaje_ganancia : null,
'descuento' => $descuento !== null ? (float) $descuento : null
];
// Obtenemos productos con sus respectivos costos para recalcular el precio de venta
require_once __DIR__ . '/../models/pedidoModel.php';
$pedidomodel = new pedidoModel();
$costosProductos = $pedidomodel->obtenerCostosPorCategoria($idEditar);
if ($productomodel->actualizarPreciosPorCategoria($idEditar, $guardarData, $costosProductos)) {
$_SESSION['flash_success'] = "Datos actualizados correctamente.";
} else {
$_SESSION['flash_error'] = "No se pudo actualizar la categoría.";
}
header("Location: index.php?opt=categorias");
exit;
}
// DEFAULT (404)
default:
ob_start();
require __DIR__ . '/../views/404View.php';
return ob_get_clean();
}