34849-vm/test_pedidos.php
2026-02-17 06:21:14 +00:00

473 lines
25 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
session_start();
if (!isset($_SESSION['user_id'])) {
header('Location: login.php');
exit;
}
require_once 'db/config.php';
function getStatusStyle($status) {
$style = 'color: white;'; // Default text color
$bgColor = '#0dcaf0'; // Default info blue
switch (strtoupper(trim($status))) {
case 'ROTULADO':
$bgColor = '#ffc107'; // yellow
$style = 'color: black;';
break;
case 'EN TRANSITO':
$bgColor = '#90EE90'; // light green
$style = 'color: black;';
break;
case 'EN DESTINO':
$bgColor = '#800080'; // purple
break;
case 'COMPLETADO':
case 'COMPLETADO ✅':
$bgColor = '#198754'; // dark green
break;
case 'GESTION':
$bgColor = '#6c757d'; // secondary grey
break;
}
return "background-color: {$bgColor} !important; {$style}";
}
$pdo = db();
$user_id = $_SESSION['user_id'];
$user_role = $_SESSION['user_role'] ?? 'Asesor';
// Fetch years for the filter
$years_query = "SELECT DISTINCT YEAR(created_at) as year FROM pedidos";
if ($user_role === 'Asesor') {
$years_query .= " WHERE asesor_id = ?";
$years_stmt = $pdo->prepare($years_query);
$years_stmt->execute([$user_id]);
} else {
$years_stmt = $pdo->query($years_query);
}
$years = $years_stmt->fetchAll(PDO::FETCH_COLUMN);
// Filter logic
$selected_month = $_GET['mes'] ?? '';
$selected_year = $_GET['año'] ?? '';
$search_query = $_GET['q'] ?? '';
$sql = "SELECT p.*, u.nombre_asesor as asesor_nombre FROM pedidos p LEFT JOIN users u ON p.asesor_id = u.id WHERE p.estado = 'EN TRANSITO 🚛'";
$params = [];
if ($user_role === 'Asesor') {
$sql .= " AND p.asesor_id = ?";
$params[] = $user_id;
}
if (!empty($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 (!empty($selected_month)) {
$sql .= " AND MONTH(p.created_at) = ?";
$params[] = $selected_month;
}
if (!empty($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();
$months = [
1 => 'Enero', 2 => 'Febrero', 3 => 'Marzo', 4 => 'Abril', 5 => 'Mayo', 6 => 'Junio',
7 => 'Julio', 8 => 'Agosto', 9 => 'Septiembre', 10 => 'Octubre', 11 => 'Noviembre', 12 => 'Diciembre'
];
?>
<?php
$pageTitle = "Pedidos en Tránsito (Prueba API Shalom)";
include 'layout_header.php';
?>
<!-- Modal for tracking status -->
<div class="modal fade" id="trackingModal" tabindex="-1" aria-labelledby="trackingModalLabel" aria-hidden="true">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="trackingModalLabel">Estado del Envío - Shalom</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<p><strong>Nº De Orden:</strong> <span id="modal-order-number"></span></p>
<p><strong>Código De Orden:</strong> <span id="modal-order-code"></span></p>
<hr>
<div id="modal-tracking-status">
<p class="text-center">Consultando estado en Shalom...</p>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cerrar</button>
</div>
</div>
</div>
</div>
<?php if (isset($_SESSION['flash_message'])):
$flash = $_SESSION['flash_message'];
unset($_SESSION['flash_message']);
?>
<div class="alert alert-<?php echo htmlspecialchars($flash['type']); ?> alert-dismissible fade show" role="alert">
<?php echo htmlspecialchars($flash['message']); ?>
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>
<?php endif; ?>
<div class="card mb-4">
<div class="card-body">
<form method="GET" action="test_pedidos.php" class="row g-3 align-items-center">
<div class="col-auto">
<label for="q" class="form-label">Buscar</label>
<input type="text" name="q" id="q" class="form-control" value="<?php echo htmlspecialchars($search_query); ?>" placeholder="Nombre, DNI o Celular">
</div>
<div class="col-auto">
<label for="mes" class="form-label">Mes</label>
<select name="mes" id="mes" class="form-select">
<option value="">Todos</option>
<?php foreach ($months as $num => $name): ?>
<option value="<?php echo $num; ?>" <?php echo $selected_month == $num ? 'selected' : ''; ?>><?php echo $name; ?></option>
<?php endforeach; ?>
</select>
</div>
<div class="col-auto">
<label for="año" class="form-label">Año</label>
<select name="año" id="año" class="form-select">
<option value="">Todos</option>
<?php foreach ($years as $year): ?>
<option value="<?php echo $year; ?>" <?php echo $selected_year == $year ? 'selected' : ''; ?>><?php echo $year; ?></option>
<?php endforeach; ?>
</select>
</div>
<div class="col-auto mt-4">
<button type="submit" class="btn btn-info">Filtrar</button>
<a href="test_pedidos.php" class="btn btn-secondary">Limpiar</a>
<button type="button" id="verify-statuses-btn" class="btn btn-primary">Verificar Estados Ahora</button>
</div>
</form>
</div>
</div>
<div class="card">
<div class="card-body">
<div class="table-responsive">
<table id="pedidos-table" class="table table-striped">
<thead>
<tr>
<th>ID</th>
<th>Cliente</th>
<th>DNI</th>
<th>Celular</th>
<th>Producto</th>
<th>Sede de Envío</th>
<th>Cantidad</th>
<th>Monto Total</th>
<th>Monto Debe</th>
<th>Nº De Orden</th>
<th>Codigo De Orden</th>
<th>CLAVE</th>
<th>Estado</th>
<th>Estado Shalom</th>
<?php if ($user_role !== 'Asesor'): ?><th>Asesor</th><?php endif; ?>
<th>Fecha Creación</th>
<th>Voucher Restante</th>
<th>Acciones</th>
</tr>
</thead>
<tbody>
<?php foreach ($pedidos as $pedido): ?>
<tr id="pedido-<?php echo $pedido['id']; ?>" data-order-number="<?php echo htmlspecialchars($pedido['codigo_rastreo'] ?? ''); ?>" data-order-code="<?php echo htmlspecialchars($pedido['codigo_tracking'] ?? ''); ?>">
<td><?php echo htmlspecialchars($pedido['id']); ?></td>
<td><?php echo htmlspecialchars($pedido['nombre_completo']); ?></td>
<td><?php echo htmlspecialchars($pedido['dni_cliente'] ?? 'N/A'); ?></td>
<td>
<?php
echo htmlspecialchars($pedido['celular']);
// Prepare WhatsApp message
$nombre_cliente = $pedido['nombre_completo'];
$producto = $pedido['producto'];
$sede_envio = $pedido['sede_envio'] ?? 'su agencia de destino';
$monto_total = (float)($pedido['monto_total'] ?? 0);
$monto_debe = (float)($pedido['monto_debe'] ?? 0);
$adelanto = $monto_total - $monto_debe;
$template = "Estimado(a) {NOMBRE_CLIENTE} 👋\n"
. "Le informamos que su pedido de {PRODUCTO} ya se encuentra disponible en su ciudad 📦\n\n"
. "📍 Lugar de recojo: Shalom {SEDE_ENVIO}\n\n"
. "💰 Detalle de pago:\n\n"
. "• Monto total del pedido: S/ {MONTO_TOTAL}\n"
. "• Adelanto realizado: S/ {ADELANTO} ✅\n"
. "• Saldo pendiente: S/ {SALDO_PENDIENTE}\n\n"
. "Para continuar, le solicitamos enviar la captura de su pago restante por este medio 📄\n\n"
. "Una vez confirmado su pago ✅, le enviaremos su clave de recojo 🔐, para que pueda retirar su pedido en la agencia sin inconvenientes 📦\n\n"
. "Quedamos atentos a su confirmación.\n"
. "Muchas gracias por su confianza 🤝\n\n"
. "Floower Store 🛍️\n"
. "Área de Atención al Cliente";
$replacements = [
'{NOMBRE_CLIENTE}' => $nombre_cliente,
'{PRODUCTO}' => $producto,
'{SEDE_ENVIO}' => $sede_envio,
'{MONTO_TOTAL}' => number_format($monto_total, 2),
'{ADELANTO}' => number_format($adelanto, 2),
'{SALDO_PENDIENTE}' => number_format($monto_debe, 2)
];
$whatsappMessage = str_replace(array_keys($replacements), array_values($replacements), $template);
$whatsappMessage = urlencode($whatsappMessage);
$celular = preg_replace('/[^0-9]/', '', $pedido['celular']);
if (strlen($celular) == 9) {
$celular = '51' . $celular;
}
$whatsappUrl = "https://api.whatsapp.com/send?phone={$celular}&text={$whatsappMessage}";
?>
<div class="mt-1">
<button type="button" class="btn btn-sm btn-info" title="Consultar Estado" data-bs-toggle="modal" data-bs-target="#trackingModal" data-order-number="<?php echo htmlspecialchars($pedido['codigo_rastreo'] ?? 'N/A'); ?>" data-order-code="<?php echo htmlspecialchars($pedido['codigo_tracking'] ?? 'N/A'); ?>">🔍</button>
<a href="<?php echo $whatsappUrl; ?>" target="_blank" class="btn btn-sm btn-secondary whatsapp-icon" id="whatsapp-icon-<?php echo $pedido['id']; ?>" title="Enviar WhatsApp">💬</a>
</div>
</td>
<td><?php echo htmlspecialchars($pedido['producto']); ?></td>
<td><?php echo htmlspecialchars($pedido['sede_envio'] ?? 'N/A'); ?></td>
<td><?php echo htmlspecialchars($pedido['cantidad'] ?: 1); ?></td>
<td><?php echo htmlspecialchars($pedido['monto_total']); ?></td>
<td><?php echo htmlspecialchars($pedido['monto_debe']); ?></td>
<td>
<button type="button" class="btn btn-link tracking-btn"
data-bs-toggle="modal"
data-bs-target="#trackingModal"
data-order-number="<?php echo htmlspecialchars($pedido['codigo_rastreo'] ?? 'N/A'); ?>"
data-order-code="<?php echo htmlspecialchars($pedido['codigo_tracking'] ?? 'N/A'); ?>">
<?php echo htmlspecialchars($pedido['codigo_rastreo'] ?? 'N/A'); ?>
</button>
</td>
<td class="editable" data-id="<?php echo $pedido['id']; ?>" data-field="codigo_tracking"><?php echo htmlspecialchars($pedido['codigo_tracking'] ?? 'N/A'); ?></td>
<td class="editable" data-id="<?php echo $pedido['id']; ?>" data-field="clave"><?php echo htmlspecialchars($pedido['clave'] ?? 'N/A'); ?></td>
<td><span class="badge" style="<?php echo getStatusStyle($pedido['estado']); ?>"><?php echo ($pedido['estado'] == 'Gestion') ? 'GESTIONES ⚙️' : htmlspecialchars($pedido['estado']); ?></span></td>
<td id="live-status-<?php echo $pedido['id']; ?>"><span class="badge bg-light text-dark">Pendiente</span></td>
<?php if ($user_role !== 'Asesor'): ?><td><?php echo htmlspecialchars($pedido['asesor_nombre'] ?? 'N/A'); ?></td><?php endif; ?>
<td><?php echo htmlspecialchars($pedido['created_at']); ?></td>
<td>
<?php if (!empty($pedido['voucher_restante_path'])): ?>
<a href="<?php echo htmlspecialchars($pedido['voucher_restante_path']); ?>" target="_blank">Ver</a>
<?php else:
?>N/A
<?php endif; ?>
</td>
<td>
<a href="pedido_form.php?id=<?php echo $pedido['id']; ?>" class="btn btn-sm btn-warning">Editar</a>
<?php if ($user_role === 'Administrador'): ?>
<a href="delete_pedido.php?id=<?php echo $pedido['id']; ?>" class="btn btn-sm btn-danger" onclick="return confirm('¿Estás seguro de que quieres eliminar este pedido?');">Eliminar</a>
<?php endif; ?>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php if (empty($pedidos)): ?>
<p class="text-center">No hay pedidos que coincidan con el filtro.</p>
<?php endif; ?>
</div>
</div>
</div>
<?php include 'layout_footer.php'; ?>
<script>
// DataTable initialization and existing modal logic
$(document).ready(function() {
$("#pedidos-table").DataTable({
"language": {
"url": "//cdn.datatables.net/plug-ins/1.10.25/i18n/Spanish.json"
},
"order": [[ <?php echo ($user_role !== 'Asesor' ? 14 : 13); ?>, "desc" ]], // Adjusted index for new column
"paging": false,
"lengthChange": false,
"info": false
});
});
document.addEventListener('DOMContentLoaded', function() {
const table = document.querySelector('.table');
// Logic for editable cells (existing logic)
table.addEventListener('click', function(e) {
if (e.target && e.target.classList.contains('editable')) {
// ... (la lógica de edición en línea se mantiene igual)
}
});
// Logic for tracking modal (existing logic)
var trackingModal = document.getElementById('trackingModal');
trackingModal.addEventListener('show.bs.modal', function (event) {
var button = event.relatedTarget;
var orderNumber = button.getAttribute('data-order-number');
var orderCode = button.getAttribute('data-order-code');
var modalOrderNumberSpan = trackingModal.querySelector('#modal-order-number');
var modalOrderCodeSpan = trackingModal.querySelector('#modal-order-code');
var modalStatusDiv = trackingModal.querySelector('#modal-tracking-status');
modalOrderNumberSpan.textContent = orderNumber;
modalOrderCodeSpan.textContent = orderCode;
modalStatusDiv.innerHTML = '<p class="text-center">Consultando estado en Shalom...</p>';
if (orderNumber === 'N/A' || orderCode === 'N/A' || !orderNumber || !orderCode) {
modalStatusDiv.innerHTML = '<p class="text-danger text-center">No hay suficientes datos (Nº de Orden o Código de Orden) para consultar.</p>';
return;
}
fetch(`shalom_api.php?orderNumber=${encodeURIComponent(orderNumber)}&orderCode=${encodeURIComponent(orderCode)}`)
.then(response => {
if (!response.ok) {
return response.json().then(errorData => {
throw new Error(errorData.error || `Error del servidor: ${response.status}`);
});
}
return response.json();
})
.then(data => {
if (data.error) {
modalStatusDiv.innerHTML = `<p class="text-danger text-center"><strong>Error:</strong> ${data.error}</p>`;
} else if (data.search && data.search.success) {
const searchData = data.search.data;
const statusData = data.statuses.data;
const statusMessage = data.statuses.message || 'No disponible';
let html = `<div class="alert alert-info text-center"><h5 class="alert-heading mb-0">Estado: ${statusMessage}</h5></div>`;
const timeline = [
{ name: 'Registrado', data: statusData.registrado },
{ name: 'En Origen', data: statusData.origen },
{ name: 'En Tránsito', data: statusData.transito },
{ name: 'En Destino', data: statusData.destino },
{ name: 'En Reparto', data: statusData.reparto },
{ name: 'Entregado', data: statusData.entregado }
];
html += '<div class="card mt-3"><div class="card-header"><strong>Historial de Estados</strong></div><div class="card-body" style="font-size: 0.9rem;">';
timeline.forEach(item => {
if (item.data && item.data.fecha) {
html += `<p class="mb-1"><strong>${item.name}:</strong> <span class="text-success">${new Date(item.data.fecha).toLocaleString('es-PE', { timeZone: 'America/Lima' })}</span></p>`;
} else {
html += `<p class="mb-1"><strong>${item.name}:</strong> <span class="text-muted">Pendiente</span></p>`;
}
});
html += '</div></div>';
modalStatusDiv.innerHTML = html;
} else {
modalStatusDiv.innerHTML = `<p class="text-warning text-center">No se pudo encontrar la guía.</p>`;
}
})
.catch(error => {
console.error('Error fetching tracking status:', error);
modalStatusDiv.innerHTML = `<p class="text-danger text-center"><strong>Error al consultar:</strong> ${error.message}</p>`;
});
});
// --- NEW ---
function verificarEstados() {
const rows = document.querySelectorAll('tr[data-order-number][data-order-code]');
const verifyButton = document.getElementById('verify-statuses-btn');
if(verifyButton) {
verifyButton.disabled = true;
verifyButton.innerHTML = '<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> Verificando...';
}
rows.forEach((row, index) => {
setTimeout(() => {
const orderNumber = row.dataset.orderNumber;
const orderCode = row.dataset.orderCode;
const pedidoId = row.id.split('-')[1];
const statusCell = document.getElementById(`live-status-${pedidoId}`);
const whatsappIcon = document.getElementById(`whatsapp-icon-${pedidoId}`);
if (!statusCell) return;
if (!orderNumber || !orderCode || orderNumber === 'N/A' || orderCode === 'N/A') {
statusCell.innerHTML = '<span class="badge bg-light text-dark">Sin datos</span>';
return;
}
statusCell.innerHTML = '<span class="badge bg-info text-dark">Verificando...</span>';
fetch(`shalom_api.php?orderNumber=${encodeURIComponent(orderNumber)}&orderCode=${encodeURIComponent(orderCode)}`)
.then(response => {
if (!response.ok) { throw new Error('Network response was not ok.'); }
return response.json();
})
.then(data => {
if (data.error) {
statusCell.innerHTML = `<span class="badge bg-danger" title="${data.error}">Error</span>`;
} else if (data.statuses && data.statuses.message) {
const statusMessage = data.statuses.message;
let badgeClass = 'bg-secondary';
let whatsappClass = 'btn-secondary';
if (statusMessage.toUpperCase().includes('EN DESTINO')) {
badgeClass = 'bg-success';
whatsappClass = 'btn-success'; // Green
} else if (statusMessage.toUpperCase().includes('EN TRANSITO')) {
badgeClass = 'bg-primary';
} else if (statusMessage.toUpperCase().includes('REGISTRADO')) {
badgeClass = 'bg-warning text-dark';
}
statusCell.innerHTML = `<span class="badge ${badgeClass}">${statusMessage}</span>`;
if (whatsappIcon) {
whatsappIcon.classList.remove('btn-secondary', 'btn-success');
whatsappIcon.classList.add(whatsappClass);
}
} else {
statusCell.innerHTML = '<span class="badge bg-warning text-dark">Inválido</span>';
}
})
.catch(error => {
console.error('Error fetching status:', error);
statusCell.innerHTML = '<span class="badge bg-danger">Fallo</span>';
})
.finally(() => {
// Re-enable button after the last request is done
if (index === rows.length - 1 && verifyButton) {
verifyButton.disabled = false;
verifyButton.innerHTML = 'Verificar Estados Ahora';
}
});
}, index * 500); // Stagger requests to avoid overwhelming the server/API
});
}
// Initial check on page load
verificarEstados();
// Add event listener for the manual verification button
const verifyButton = document.getElementById('verify-statuses-btn');
if (verifyButton) {
verifyButton.addEventListener('click', verificarEstados);
}
});
</script>