diff --git a/recaudo_esperado.php b/recaudo_esperado.php index e6499d2..3da368d 100644 --- a/recaudo_esperado.php +++ b/recaudo_esperado.php @@ -10,132 +10,18 @@ if (!isset($_SESSION['user_id']) || !isset($_SESSION['user_role']) || $_SESSION[ $pdo = db(); -// --- DATE FILTER (from finanzas.php) --- +// --- DATE FILTER --- $fecha_inicio_str = $_POST['fecha_inicio'] ?? ''; $fecha_fin_str = $_POST['fecha_fin'] ?? ''; -$fecha_inicio_obj = null; -if (!empty($fecha_inicio_str)) { - $fecha_inicio_obj = DateTime::createFromFormat('Y-m-d', $fecha_inicio_str); -} - -$fecha_fin_obj = null; -if (!empty($fecha_fin_str)) { - $fecha_fin_obj = DateTime::createFromFormat('Y-m-d', $fecha_fin_str); -} - -$where_clause = ''; $params = []; - -if ($fecha_inicio_obj && $fecha_fin_obj) { - $where_conditions = ["p.estado = 'Completado'", "p.estado_pago = 'Pendiente'"]; -$params = []; - -if ($fecha_inicio_obj && $fecha_fin_obj) { - $where_conditions[] = 'p.created_at BETWEEN ? AND ?'; - $params[] = $fecha_inicio_obj->format('Y-m-d 00:00:00'); - $params[] = $fecha_fin_obj->format('Y-m-d 23:59:59'); +$date_where_clause = ""; +if (!empty($fecha_inicio_str) && !empty($fecha_fin_str)) { + $date_where_clause = " WHERE p.fecha_pedido BETWEEN ? AND ?"; + $params[] = $fecha_inicio_str; + $params[] = $fecha_fin_str; } -$where_clause = ' WHERE ' . implode(' AND ', $where_conditions); - - -// --- RECAUDO ESPERADO POR ASESORA -- -$asesoras_recuado = []; -try { - $sql_asesoras = " - SELECT - u.nombre_asesor AS asesora_nombre, - SUM(p.monto_total) AS monto_total, - COUNT(p.id) AS cantidad_pedidos - FROM users u - JOIN pedidos p ON u.id = p.asesor_id - {$where_clause} - GROUP BY u.id, u.nombre_asesor - ORDER BY monto_total DESC - "; - - $stmt_asesoras = $pdo->prepare($sql_asesoras); - $stmt_asesoras->execute($params); - $asesoras_recuado = $stmt_asesoras->fetchAll(PDO::FETCH_ASSOC); - -} catch (PDOException $e) { - error_log("Error en RECAUDO POR ASESORA: " . $e->getMessage()); -} - -// --- RESUMEN GENERAL Y POR ASESOR (VERSIÓN CORREGIDA) --- -$productos_resumen = []; -$resumen_por_asesor = []; -$pedidos = []; // Inicializar para que exista siempre - -try { - // 1. Obtener precios de productos - $precios_productos = $pdo->query("SELECT nombre, price FROM products")->fetchAll(PDO::FETCH_KEY_PAIR); - - // 2. Obtener todos los pedidos relevantes - $sql_pedidos = " - SELECT - p.producto, - p.cantidad, - COALESCE(u.nombre_asesor, u.username, 'Sin Asesor') AS asesor_nombre - FROM pedidos p - LEFT JOIN users u ON p.asesor_id = u.id - {$where_clause} - "; - $stmt_pedidos = $pdo->prepare($sql_pedidos); - $stmt_pedidos->execute($params); - $pedidos = $stmt_pedidos->fetchAll(PDO::FETCH_ASSOC); // Traer todos los pedidos a un array - - // 3. Procesar pedidos en PHP - foreach ($pedidos as $pedido) { // Iterar sobre el array - $asesor = $pedido['asesor_nombre']; - $nombres = explode(',', $pedido['producto']); - $cantidades = explode(',', $pedido['cantidad']); - - foreach ($nombres as $index => $nombre) { - $nombre = trim($nombre); - if (empty($nombre)) continue; - - $cantidad = isset($cantidades[$index]) ? (int)trim($cantidades[$index]) : 0; - $precio = isset($precios_productos[$nombre]) ? (float)$precios_productos[$nombre] : 0; - $monto = $cantidad * $precio; - - // Acumular para Resumen General - if (!isset($productos_resumen[$nombre])) { - $productos_resumen[$nombre] = ['cantidad' => 0, 'monto' => 0, 'num_pedidos' => 0]; - } - $productos_resumen[$nombre]['cantidad'] += $cantidad; - $productos_resumen[$nombre]['monto'] += $monto; - $productos_resumen[$nombre]['num_pedidos']++; - - // Acumular para Desglose por Asesor - if (!isset($resumen_por_asesor[$asesor][$nombre])) { - $resumen_por_asesor[$asesor][$nombre] = ['cantidad' => 0, 'monto' => 0, 'num_pedidos' => 0]; - } - $resumen_por_asesor[$asesor][$nombre]['cantidad'] += $cantidad; - $resumen_por_asesor[$asesor][$nombre]['monto'] += $monto; - $resumen_por_asesor[$asesor][$nombre]['num_pedidos']++; - } - } - - // 4. Ordenar resultados - uasort($productos_resumen, function($a, $b) { return $b['cantidad'] <=> $a['cantidad']; }); - foreach ($resumen_por_asesor as &$productos) { - uasort($productos, function($a, $b) { return $b['cantidad'] <=> $a['cantidad']; }); - } - unset($productos); - -} catch (PDOException $e) { - error_log("Error en RESUMEN GENERAL DE PRODUCTOS: " . $e->getMessage()); - $productos_resumen = []; - $resumen_por_asesor = []; - $pedidos = []; // Asegurar que se reinicia en caso de error -} - $params[] = $fecha_inicio_obj->format('Y-m-d 00:00:00'); - $params[] = $fecha_fin_obj->format('Y-m-d 23:59:59'); -} - - // --- RECAUDO ESPERADO POR ASESORA --- $asesoras_recuado = []; try { @@ -146,7 +32,7 @@ try { COUNT(p.id) AS cantidad_pedidos FROM users u JOIN pedidos p ON u.id = p.asesor_id - {$where_clause} + {$date_where_clause} GROUP BY u.id, u.nombre_asesor ORDER BY monto_total DESC "; @@ -159,86 +45,72 @@ try { error_log("Error en RECAUDO POR ASESORA: " . $e->getMessage()); } -// --- RESUMEN GENERAL Y POR ASESOR (VERSIÓN CORREGIDA) --- -$productos_resumen = []; -$resumen_por_asesor = []; -$pedidos = []; // Inicializar para que exista siempre +// --- RESUMEN GENERAL Y POR ASESOR --- +$productos_vendidos = []; +$ventas_por_asesor = []; try { - // 1. Obtener precios de productos - $precios_productos = $pdo->query("SELECT nombre, price FROM products")->fetchAll(PDO::FETCH_KEY_PAIR); + $sql_productos_base = "SELECT + p.cantidad as cantidades_pedido, + p.producto_id as productos_pedido_ids, + pr.id as producto_id, + pr.nombre as producto_nombre, + pr.precio as producto_precio, + u.nombre_asesor + FROM + pedidos p + JOIN + productos pr ON FIND_IN_SET(pr.id, REPLACE(p.producto_id, ' ', '')) + LEFT JOIN + users u ON p.asesor_id = u.id + {$date_where_clause}"; - // 2. Obtener todos los pedidos relevantes - $sql_pedidos = " - SELECT - p.producto, - p.cantidad, - COALESCE(u.nombre_asesor, u.username, 'Sin Asesor') AS asesor_nombre - FROM pedidos p - LEFT JOIN users u ON p.asesor_id = u.id - {$where_clause} - "; - $stmt_pedidos = $pdo->prepare($sql_pedidos); - $stmt_pedidos->execute($params); - $pedidos = $stmt_pedidos->fetchAll(PDO::FETCH_ASSOC); // Traer todos los pedidos a un array + $stmt_productos = $pdo->prepare($sql_productos_base); + $stmt_productos->execute($params); + $result_productos = $stmt_productos->fetchAll(PDO::FETCH_ASSOC); - // 3. Procesar pedidos en PHP - foreach ($pedidos as $pedido) { // Iterar sobre el array - $asesor = $pedido['asesor_nombre']; - $nombres = explode(',', $pedido['producto']); - $cantidades = explode(',', $pedido['cantidad']); + if ($result_productos) { + foreach ($result_productos as $row) { + $todos_productos_ids = explode(',', $row['productos_pedido_ids']); + $todas_cantidades = explode(',', $row['cantidades_pedido']); - foreach ($nombres as $index => $nombre) { - $nombre = trim($nombre); - if (empty($nombre)) continue; + $product_index = array_search($row['producto_id'], $todos_productos_ids); - $cantidad = isset($cantidades[$index]) ? (int)trim($cantidades[$index]) : 0; - $precio = isset($precios_productos[$nombre]) ? (float)$precios_productos[$nombre] : 0; - $monto = $cantidad * $precio; + if ($product_index !== false && isset($todas_cantidades[$product_index])) { + $cantidad_producto = (int)trim($todas_cantidades[$product_index]); + $producto_nombre = $row['producto_nombre']; + $asesor_nombre = $row['nombre_asesor'] ?? 'Sin Asesor'; + $monto_producto = $cantidad_producto * (float)$row['producto_precio']; - // Acumular para Resumen General - if (!isset($productos_resumen[$nombre])) { - $productos_resumen[$nombre] = ['cantidad' => 0, 'monto' => 0, 'num_pedidos' => 0]; + // Acumular para "Resumen General de Productos Vendidos" + if (!isset($productos_vendidos[$producto_nombre])) { + $productos_vendidos[$producto_nombre] = ['unidades' => 0, 'monto' => 0]; + } + $productos_vendidos[$producto_nombre]['unidades'] += $cantidad_producto; + $productos_vendidos[$producto_nombre]['monto'] += $monto_producto; + + // Acumular para "Desglose de Ventas por Asesor" + if (!isset($ventas_por_asesor[$asesor_nombre])) { + $ventas_por_asesor[$asesor_nombre] = []; + } + if (!isset($ventas_por_asesor[$asesor_nombre][$producto_nombre])) { + $ventas_por_asesor[$asesor_nombre][$producto_nombre] = ['unidades' => 0, 'monto' => 0]; + } + $ventas_por_asesor[$asesor_nombre][$producto_nombre]['unidades'] += $cantidad_producto; + $ventas_por_asesor[$asesor_nombre][$producto_nombre]['monto'] += $monto_producto; } - $productos_resumen[$nombre]['cantidad'] += $cantidad; - $productos_resumen[$nombre]['monto'] += $monto; - $productos_resumen[$nombre]['num_pedidos']++; - - // Acumular para Desglose por Asesor - if (!isset($resumen_por_asesor[$asesor][$nombre])) { - $resumen_por_asesor[$asesor][$nombre] = ['cantidad' => 0, 'monto' => 0, 'num_pedidos' => 0]; - } - $resumen_por_asesor[$asesor][$nombre]['cantidad'] += $cantidad; - $resumen_por_asesor[$asesor][$nombre]['monto'] += $monto; - $resumen_por_asesor[$asesor][$nombre]['num_pedidos']++; } } - - // 4. Ordenar resultados - uasort($productos_resumen, function($a, $b) { return $b['cantidad'] <=> $a['cantidad']; }); - foreach ($resumen_por_asesor as &$productos) { - uasort($productos, function($a, $b) { return $b['cantidad'] <=> $a['cantidad']; }); - } - unset($productos); - } catch (PDOException $e) { - error_log("Error en RESUMEN GENERAL DE PRODUCTOS: " . $e->getMessage()); - $productos_resumen = []; - $resumen_por_asesor = []; - $pedidos = []; // Asegurar que se reinicia en caso de error + error_log("Error en RESUMEN DE PRODUCTOS: " . $e->getMessage()); } - - - include 'layout_header.php'; - ?>
No hay datos de ventas para mostrar.
- $productos): ?> + $productos): ?>| Producto | -Cantidad de Pedidos | Unidades Vendidas | Monto Total | |
|---|---|---|---|---|
| = htmlspecialchars($nombre_producto) ?> | -= $datos['num_pedidos'] ?> | -= $datos['cantidad'] ?> unidades | += $datos['unidades'] ?> unidades | S/ = number_format($datos['monto'], 2) ?> |