+
\ No newline at end of file diff --git a/index.php b/index.php index 7205f3d..6d6d99a 100644 --- a/index.php +++ b/index.php @@ -1,150 +1,258 @@ query("SELECT COUNT(*) FROM productos"); +$total_products = $stmt->fetchColumn(); + +// Obtener stock por ciudad y producto, ordenando las ciudades por stock total +$stock_stmt = $pdo->query(" + SELECT + c.nombre AS ciudad, + p.nombre AS producto, + s.stock_actual + FROM + stock_por_ciudad s + JOIN + ciudades c ON s.ciudad_id = c.id + JOIN + productos p ON s.producto_id = p.id + JOIN + (SELECT ciudad_id, SUM(stock_actual) as total_stock FROM stock_por_ciudad GROUP BY ciudad_id) as stock_totales + ON c.id = stock_totales.ciudad_id + WHERE + s.stock_actual > 0 + ORDER BY + stock_totales.total_stock DESC, p.nombre; +"); +$stock_data = $stock_stmt->fetchAll(PDO::FETCH_ASSOC); + +// Agrupar por ciudad +$stock_por_ciudad = []; +foreach ($stock_data as $row) { + $stock_por_ciudad[$row['ciudad']][] = [ + 'producto' => $row['producto'], + 'stock' => $row['stock_actual'] + ]; +} -$phpVersion = PHP_VERSION; -$now = date('Y-m-d H:i:s'); ?> - - - - - - New Style - - - - - - - - - - - - - - - - - - - - - -
-
-

Analyzing your requirements and generating your website…

-
- Loading… -
-

AI is collecting your requirements and applying the first changes.

-

This page will update automatically as the plan is implemented.

-

Runtime: PHP — UTC

+ +
+ +
+
+

Bienvenido a tu Panel de Control

+

Aquí tienes un resumen de tu aplicación.

+
-
-
- Page updated: (UTC) -
- - + +
+ +
+
+
+
+
+ + +
+
+
Total de Productos
+

+
+
+
+
+
+ + + + + +
+
+
+
Distribución de Stock
+
+ +
+
+
+
+
+ +
+ +
+
+
+
Stock por Ciudad y Producto
+
+ +

No hay datos de stock disponibles.

+ + $productos): + $ciudad_id = 'ciudad_' . $i++; + ?> +
+

+ +

+
+
+
+ + + + + + + + + + + + + + + +
ProductoStock
+
+
+
+
+ + +
+
+
+
+
+
+ + [ + 'bg' => 'rgba(40, 167, 69, 0.8)', // Verde fondo + 'border' => 'rgba(40, 167, 69, 1)' // Verde borde + ] +]; + +if (!empty($stock_por_ciudad)) { + $color_index = 0; + foreach ($stock_por_ciudad as $ciudad => $productos) { + $chart_labels[] = $ciudad; + + // Asignar color + if (isset($city_color_map[$ciudad])) { + $chart_bg_colors[] = $city_color_map[$ciudad]['bg']; + $chart_border_colors[] = $city_color_map[$ciudad]['border']; + } else { + // Asignar un color de la paleta + $chart_bg_colors[] = $color_palette_bg[$color_index % count($color_palette_bg)]; + $chart_border_colors[] = $color_palette_border[$color_index % count($color_palette_border)]; + $color_index++; + } + + $total_stock = 0; + foreach ($productos as $producto) { + $total_stock += $producto['stock']; + } + $chart_data[] = $total_stock; + } +} +?> + + + + diff --git a/info_producto.php b/info_producto.php new file mode 100644 index 0000000..4b042ea --- /dev/null +++ b/info_producto.php @@ -0,0 +1,100 @@ +query('SELECT id, nombre FROM productos ORDER BY nombre ASC'); +$productos = $stmt_productos->fetchAll(PDO::FETCH_ASSOC); + +// Fetch Kanban columns for the dropdown +$stmt_columns = $pdo->query('SELECT id, nombre FROM kanban_columns ORDER BY orden ASC'); +$columns = $stmt_columns->fetchAll(PDO::FETCH_ASSOC); + +// If no columns exist, create default ones to ensure the dropdown is never empty +if (empty($columns)) { + $default_columns = ['Para empezar', 'En proceso', 'Terminado']; + $stmt_insert = $pdo->prepare('INSERT INTO kanban_columns (nombre, orden) VALUES (?, ?)'); + foreach ($default_columns as $index => $name) { + $stmt_insert->execute([$name, $index + 1]); + } + // Re-fetch columns so they appear on this page load + $stmt_columns = $pdo->query('SELECT id, nombre FROM kanban_columns ORDER BY orden ASC'); + $columns = $stmt_columns->fetchAll(PDO::FETCH_ASSOC); +} + +// Fetch existing info cards +$stmt_info = $pdo->query('SELECT info_productos.id, productos.nombre as producto_nombre, info_productos.imagen_url, info_productos.texto_informativo, kanban_columns.nombre as columna_nombre FROM info_productos JOIN productos ON info_productos.producto_id = productos.id LEFT JOIN kanban_columns ON info_productos.column_id = kanban_columns.id ORDER BY info_productos.created_at DESC'); +$info_cards = $stmt_info->fetchAll(PDO::FETCH_ASSOC); +?> + +
+

Info de Productos

+

Crea y gestiona tarjetas con información y fotos de tus productos.

+ +
+
Agregar Nueva Tarjeta de Información
+
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+ +
+
+
+ +
+ +
+

Aún no has creado ninguna tarjeta de información.

+
+ + +
+
+ Imagen de <?php echo htmlspecialchars($card['producto_nombre']); ?> +
+
+

Columna:

+

+
+ +
+
+ + +
+
+ + \ No newline at end of file diff --git a/inversiones_operativas.php b/inversiones_operativas.php new file mode 100644 index 0000000..c60e6d3 --- /dev/null +++ b/inversiones_operativas.php @@ -0,0 +1,223 @@ + 0 && !empty($tipo)) { + try { + $stmt = $pdo->prepare("INSERT INTO inversiones (fecha, descripcion, monto, tipo) VALUES (?, ?, ?, ?)"); + $stmt->execute([$fecha, $descripcion, $monto, $tipo]); + + // Redirigir para evitar reenvío de formulario + header("Location: " . $_SERVER['PHP_SELF'] . "?success=true#section-" . $tipo); + exit; + } catch (PDOException $e) { + $error_message = "Error al guardar en la base de datos: " . $e->getMessage(); + } + } else { + $error_message = "Por favor, complete todos los campos correctamente."; + } +} + +// --- Filtrado por Mes --- +$selected_month = $_GET['mes'] ?? null; +$selected_year = $_GET['anio'] ?? null; +$filter_active = $selected_month && $selected_year; + +// --- Obtener todos los datos de inversiones (con filtro si aplica) --- +try { + $sql = "SELECT * FROM inversiones"; + $params = []; + if ($filter_active) { + $sql .= " WHERE MONTH(fecha) = ? AND YEAR(fecha) = ?"; + $params = [$selected_month, $selected_year]; + } + $sql .= " ORDER BY fecha DESC, id DESC"; + + $stmt = $pdo->prepare($sql); + $stmt->execute($params); + $all_inversiones = $stmt->fetchAll(PDO::FETCH_ASSOC); + +} catch (PDOException $e) { + die("Error al obtener los datos: " . $e->getMessage()); +} + +// --- Obtener totales por mes (esto no se filtra) --- +try { + $stmt_totals = $pdo->query(" + SELECT + DATE_FORMAT(fecha, '%Y') as anio, + DATE_FORMAT(fecha, '%m') as mes_num, + DATE_FORMAT(fecha, '%M %Y') as mes_nombre, + SUM(monto) as total_monto + FROM + inversiones + GROUP BY + anio, mes_num, mes_nombre + ORDER BY + anio DESC, mes_num DESC + "); + $monthly_totals = $stmt_totals->fetchAll(PDO::FETCH_ASSOC); +} catch (PDOException $e) { + die("Error al obtener los totales mensuales: " . $e->getMessage()); +} + + +// Separar por tipo +$inversiones_operativas = array_filter($all_inversiones, fn($inv) => $inv['tipo'] === 'operativa'); +$inversiones_operacionales = array_filter($all_inversiones, fn($inv) => $inv['tipo'] === 'operacional'); +$inversiones_ads = array_filter($all_inversiones, fn($inv) => $inv['tipo'] === 'ads'); + +// Función para renderizar una sección de inversión +function render_investment_section($title, $type, $data, $description_label) { + $total = array_sum(array_column($data, 'monto')); +?> +
+

+
+
+ +
+ +
+
+ + +
+
+ + +
+
+ + +
+
+ +
+
+
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FechaDescripciónMonto (S/)Acciones
No hay registros.
+ Editar + Eliminar +
TOTAL:
+
+
+
+
+ + +
+

Gestión de Inversiones

+
+ +
+ + +
Registro guardado exitosamente.
+ + + +
+

Resumen de Inversiones por Mes

+
+
+
+ + + + + + + + + + + + + + + + + + + + + +
MesMonto Total (S/)
No hay datos para mostrar.
+
+
+
+
+ + +
+
+

Mostrando Inversiones de:

+ Mostrar Todos los Meses +
+
+
+ + +
+ + \ No newline at end of file diff --git a/liquidaciones.php b/liquidaciones.php new file mode 100644 index 0000000..a56c95a --- /dev/null +++ b/liquidaciones.php @@ -0,0 +1,244 @@ +prepare("UPDATE movimientos SET precio_liquidacion = :precio WHERE id = :id AND tipo = 'Salida'"); + foreach ($_POST['precios'] as $movimiento_id => $precio) { + if (!empty($precio)) { + $stmt_precio->execute([':precio' => $precio, ':id' => $movimiento_id]); + $success = true; + } + } + } + + // Actualizar cantidad de pedidos + if (isset($_POST['pedidos'])) { + $stmt_pedidos = $pdo->prepare("UPDATE movimientos SET cantidad_pedidos = :pedidos WHERE id = :id AND tipo = 'Salida'"); + foreach ($_POST['pedidos'] as $movimiento_id => $pedidos) { + if (!empty($pedidos)) { + $stmt_pedidos->execute([':pedidos' => $pedidos, ':id' => $movimiento_id]); + $success = true; + } + } + } + + if ($success) { + echo '
Liquidaciones actualizadas correctamente.
'; + } +} + +// Obtener todos los movimientos de salida +$pdo = db(); +$stmt = $pdo->query(" + SELECT + m.id, + m.fecha, + p.nombre as producto, + m.cantidad, + c.nombre as ciudad, + m.precio_liquidacion, + m.cantidad_pedidos + FROM movimientos m + JOIN productos p ON m.producto_id = p.id + JOIN ciudades c ON m.ciudad_origen_id = c.id + WHERE m.tipo = 'Salida' + ORDER BY DATE(m.fecha) DESC, c.nombre, p.nombre +"); + +$salidas = $stmt->fetchAll(PDO::FETCH_ASSOC); + +// Agrupar salidas por fecha +$salidas_por_fecha = []; +foreach ($salidas as $salida) { + $fecha = date('Y-m-d', strtotime($salida['fecha'])); + $salidas_por_fecha[$fecha][] = $salida; +} + +// Obtener productos y ciudades para el formulario +$productos = $pdo->query("SELECT id, nombre FROM productos ORDER BY nombre")->fetchAll(); +$ciudades = $pdo->query("SELECT id, nombre FROM ciudades ORDER BY nombre")->fetchAll(); + +$user_rol = $_SESSION['user_rol'] ?? ''; + +?> + +

Liquidaciones de Salidas

+ +Liquidación agregada correctamente.