40097-vm/download_ruta_contraentrega.php
2026-05-23 23:40:36 +00:00

174 lines
4.8 KiB
PHP

<?php
session_start();
if (!isset($_SESSION['user_id'])) {
header('Location: login.php');
exit;
}
require_once 'db/config.php';
require_once 'vendor/autoload.php';
use Shuchkin\SimpleXLSXGen;
function splitProvinciaDistrito(?string $value): array
{
$value = trim((string)$value);
if ($value === '') {
return ['', ''];
}
$clean = preg_replace('/\s+/', ' ', $value);
$parts = preg_split('/\s*[\/\-,|]\s*/', $clean, 2);
if (is_array($parts) && count($parts) === 2) {
return [trim($parts[0]), trim($parts[1])];
}
return [$clean, ''];
}
function extractProductNames(array $pedido): array
{
$names = [];
$notas = (string)($pedido['notas'] ?? '');
if (preg_match('/Detalle de productos:\s*(.+)$/mi', $notas, $match)) {
$items = explode(',', $match[1]);
foreach ($items as $item) {
$name = preg_replace('/\s*\(x\d+\)\s*$/i', '', trim($item));
if ($name !== '') {
$names[] = $name;
}
}
}
if (empty($names) && !empty($pedido['producto'])) {
foreach (explode(',', (string)$pedido['producto']) as $item) {
$name = trim($item);
if ($name !== '') {
$names[] = $name;
}
}
}
return array_values(array_unique($names));
}
function getEansForProducts(PDO $pdo, array $productNames): string
{
if (empty($productNames)) {
return '';
}
$placeholders = implode(',', array_fill(0, count($productNames), '?'));
$stmt = $pdo->prepare("SELECT nombre, ean FROM products WHERE nombre IN ($placeholders)");
$stmt->execute($productNames);
$map = [];
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
$ean = trim((string)($row['ean'] ?? ''));
if ($ean !== '') {
$map[$row['nombre']] = $ean;
}
}
$eans = [];
foreach ($productNames as $name) {
if (!empty($map[$name])) {
$eans[] = $map[$name];
}
}
return implode(' | ', array_values(array_unique($eans)));
}
try {
$pdo = db();
$user_id = $_SESSION['user_id'];
$user_role = $_SESSION['user_role'] ?? 'Asesor';
$selected_month = $_GET['mes'] ?? '';
$selected_year = $_GET['año'] ?? '';
$search_query = trim($_GET['q'] ?? '');
$sql = "SELECT p.* FROM pedidos p WHERE p.estado IN ('RUTA_CONTRAENTREGA', 'PENDIENTE', 'NO CONTESTO, VOLVER A LLAMAR', 'NO CONTESTO, DEVOLVER LLAMADA', 'CANCELADO', 'REPROGRAMADO', 'ENTREGA EXITOSA', 'RETORNADO')";
$params = [];
if ($user_role === 'Asesor') {
$sql .= " AND p.asesor_id = ?";
$params[] = $user_id;
}
if ($search_query !== '') {
$sql .= " AND (p.nombre_completo LIKE ? OR p.dni_cliente LIKE ? OR p.celular LIKE ?)";
$params[] = "%$search_query%";
$params[] = "%$search_query%";
$params[] = "%$search_query%";
}
if ($selected_month !== '') {
$sql .= " AND MONTH(p.created_at) = ?";
$params[] = $selected_month;
}
if ($selected_year !== '') {
$sql .= " AND YEAR(p.created_at) = ?";
$params[] = $selected_year;
}
$sql .= " ORDER BY p.created_at DESC";
$stmt = $pdo->prepare($sql);
$stmt->execute($params);
$pedidos = $stmt->fetchAll(PDO::FETCH_ASSOC);
$rows = [];
$rows[] = [
'Nombre y apellido',
'Celular',
'Pais',
'Departamento',
'Provincia',
'Distrito',
'Direccion',
'Referencia',
'Coordenadas',
'Codigo EAN',
'Cantidad',
'Precio',
'Total'
];
foreach ($pedidos as $pedido) {
[$provincia, $distrito] = splitProvinciaDistrito($pedido['codigo_rastreo'] ?? '');
$cantidad = (int)($pedido['cantidad'] ?? 0);
$total = (float)($pedido['monto_total'] ?? 0);
$precio = $cantidad > 0 ? round($total / $cantidad, 2) : 0;
$ean = getEansForProducts($pdo, extractProductNames($pedido));
$rows[] = [
(string)($pedido['nombre_completo'] ?? ''),
(string)($pedido['celular'] ?? ''),
'Perú',
(string)($pedido['sede_envio'] ?? ''),
$provincia,
$distrito,
(string)($pedido['direccion_exacta'] ?? ''),
(string)($pedido['referencia_domicilio'] ?? ''),
(string)($pedido['coordenadas'] ?? ''),
(string)$ean,
$cantidad,
$precio,
$total
];
}
$filename = 'ruta_contraentrega_' . date('Y-m-d_H-i') . '.xlsx';
SimpleXLSXGen::fromArray($rows, 'Ruta Contraentrega')->downloadAs($filename);
exit;
} catch (Throwable $e) {
error_log('Error exportando Ruta Contraentrega: ' . $e->getMessage());
header('HTTP/1.1 500 Internal Server Error');
echo 'Error al generar el Excel de Ruta Contraentrega.';
}