636 lines
35 KiB
PHP
636 lines
35 KiB
PHP
<?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";
|
||
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="pedidos_en_transito.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="pedidos_en_transito.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>Agencia</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} 👋
|
||
"
|
||
. "Le informamos que su pedido de {PRODUCTO} ya se encuentra disponible en su ciudad 📦
|
||
|
||
"
|
||
. "📍 Lugar de recojo: Shalom – {SEDE_ENVIO}
|
||
|
||
"
|
||
. "💰 Detalle de pago:
|
||
|
||
"
|
||
. "• Monto total del pedido: S/ {MONTO_TOTAL}
|
||
"
|
||
. "• Adelanto realizado: S/ {ADELANTO} ✅
|
||
"
|
||
. "• Saldo pendiente: S/ {SALDO_PENDIENTE}
|
||
|
||
"
|
||
. "Para continuar, le solicitamos enviar la captura de su pago restante por este medio 📄
|
||
|
||
"
|
||
. "Una vez confirmado su pago ✅, le enviaremos su clave de recojo 🔐, para que pueda retirar su pedido en la agencia sin inconvenientes 📦
|
||
|
||
"
|
||
. "Quedamos atentos a su confirmación.
|
||
"
|
||
. "Muchas gracias por su confianza 🤝
|
||
|
||
"
|
||
. "Floower Store 🛍️
|
||
"
|
||
. "Á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="https://rastrea.shalom.pe/rastrea" target="_blank" class="btn btn-sm btn-primary" title="Rastreo Shalom">🚚</a>
|
||
<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['agencia'] ?? 'SHALOM'); ?></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><?php echo htmlspecialchars($pedido['codigo_rastreo'] ?? 'N/A'); ?></td>
|
||
<td class="editable" data-id="<?php echo $pedido['id']; ?>" data-field="codigo_tracking"><?php echo htmlspecialchars($pedido['codigo_tracking'] ?? 'N/A'); ?></td>
|
||
<?php
|
||
$canSeeClave = ($user_role !== 'Asesor' || (!empty($pedido['numero_operacion']) && !empty($pedido['banco'])));
|
||
$isEditableClave = ($user_role !== 'Asesor') ? 'editable' : '';
|
||
?>
|
||
<td class="<?php echo $isEditableClave; ?>" data-id="<?php echo $pedido['id']; ?>" data-field="clave">
|
||
<?php echo $canSeeClave ? htmlspecialchars($pedido['clave'] ?? 'N/A') : '<i class="fas fa-eye-slash text-muted" title="Suba el número de operación y seleccione el banco para ver la clave"></i> <span class="text-muted" style="font-size: 0.8rem;">Oculto</span>'; ?>
|
||
</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": [[ 0, "desc" ]],
|
||
"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 statusIcon = '';
|
||
let statusColor = '#003399';
|
||
let statusBg = '#fff9e6'; // Light yellow background
|
||
|
||
const upperStatus = statusMessage.toUpperCase();
|
||
if (upperStatus.includes('ENTREGADO')) {
|
||
statusColor = '#198754';
|
||
statusBg = '#e9f7ef';
|
||
statusIcon = `
|
||
<svg width="140" height="140" viewBox="0 0 140 140" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||
<circle cx="70" cy="70" r="65" fill="#198754" fill-opacity="0.1" stroke="#198754" stroke-width="2"/>
|
||
<!-- Box -->
|
||
<g transform="translate(40, 60)">
|
||
<path d="M0 10L30 20V50L0 40V10Z" fill="#e30613"/>
|
||
<path d="M30 20L60 10V40L30 50V20Z" fill="#b90510"/>
|
||
<path d="M0 10L30 0L60 10L30 20L0 10Z" fill="#f14b55"/>
|
||
<text x="5" y="35" fill="white" font-family="Arial Black, sans-serif" font-weight="900" font-style="italic" font-size="7" transform="skewY(15)">SHALOM</text>
|
||
</g>
|
||
<!-- Checkmark -->
|
||
<circle cx="100" cy="40" r="25" fill="#198754"/>
|
||
<path d="M88 40L96 48L112 32" stroke="white" stroke-width="6" stroke-linecap="round" stroke-linejoin="round"/>
|
||
</svg>`;
|
||
} else if (upperStatus.includes('DESTINO')) {
|
||
statusColor = '#003399';
|
||
statusBg = '#eef2ff';
|
||
statusIcon = `
|
||
<svg width="140" height="140" viewBox="0 0 140 140" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||
<!-- Dashed Path -->
|
||
<path d="M30 60C40 60 45 90 65 90C85 90 90 60 100 60" stroke="#cbd5e1" stroke-width="3" stroke-dasharray="6 6" />
|
||
|
||
<!-- Small Pin -->
|
||
<g transform="translate(22, 45) scale(0.6)">
|
||
<path d="M12 0C5.37 0 0 5.37 0 12C0 21 12 34 12 34C12 34 24 21 24 12C24 5.37 18.63 0 12 0Z" fill="#1e293b"/>
|
||
<circle cx="12" cy="12" r="4" fill="white"/>
|
||
</g>
|
||
|
||
<!-- Box -->
|
||
<g transform="translate(45, 75)">
|
||
<!-- Front Face -->
|
||
<path d="M0 15L35 25V55L0 45V15Z" fill="#e30613"/>
|
||
<!-- Right Face -->
|
||
<path d="M35 25L60 15V45L35 55V25Z" fill="#b90510"/>
|
||
<!-- Top Face -->
|
||
<path d="M0 15L25 5L60 15L35 25L0 15Z" fill="#f14b55"/>
|
||
<!-- White Stripe -->
|
||
<path d="M12 10L30 16L50 10L32 4L12 10Z" fill="white"/>
|
||
<!-- Shalom Text -->
|
||
<text x="4" y="40" fill="white" font-family="Arial Black, sans-serif" font-weight="900" font-style="italic" font-size="7" transform="skewY(15)">SHALOM</text>
|
||
</g>
|
||
|
||
<!-- Large Pin -->
|
||
<g transform="translate(70, 30)">
|
||
<path d="M20 0C8.95 0 0 8.95 0 20C0 35 20 55 20 55C20 55 40 35 40 20C40 8.95 31.05 0 20 0Z" fill="#003399"/>
|
||
<circle cx="20" cy="20" r="8" fill="white"/>
|
||
</g>
|
||
</svg>`;
|
||
} else if (upperStatus.includes('TRANSITO') || upperStatus.includes('TRÁNSITO')) {
|
||
statusColor = '#ffc107';
|
||
statusBg = '#fff9e6';
|
||
statusIcon = `
|
||
<svg width="140" height="140" viewBox="0 0 140 140" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||
<circle cx="70" cy="70" r="65" fill="#ffc107" fill-opacity="0.1" stroke="#ffc107" stroke-width="2"/>
|
||
<!-- Road -->
|
||
<path d="M20 105H120" stroke="#6c757d" stroke-width="4" stroke-linecap="round" stroke-dasharray="8 8"/>
|
||
<!-- Truck Body -->
|
||
<rect x="30" y="55" width="60" height="40" rx="2" fill="#003399"/>
|
||
<!-- Truck Cabin -->
|
||
<path d="M90 65H105L115 80V95H90V65Z" fill="#003399"/>
|
||
<!-- Window -->
|
||
<path d="M95 70H103L108 80H95V70Z" fill="#eef2ff"/>
|
||
<!-- Wheels -->
|
||
<circle cx="45" cy="100" r="8" fill="#1e293b"/>
|
||
<circle cx="45" cy="100" r="4" fill="#94a3b8"/>
|
||
<circle cx="75" cy="100" r="8" fill="#1e293b"/>
|
||
<circle cx="75" cy="100" r="4" fill="#94a3b8"/>
|
||
<circle cx="105" cy="100" r="8" fill="#1e293b"/>
|
||
<circle cx="105" cy="100" r="4" fill="#94a3b8"/>
|
||
<!-- Shalom Text on Truck -->
|
||
<text x="35" y="80" fill="white" font-family="Arial Black, sans-serif" font-weight="900" font-style="italic" font-size="8">SHALOM</text>
|
||
<!-- Speed lines -->
|
||
<path d="M10 65H25M5 75H20M10 85H25" stroke="#ffc107" stroke-width="3" stroke-linecap="round"/>
|
||
</svg>`;
|
||
} else if (upperStatus.includes('ORIGEN')) {
|
||
statusColor = '#6c757d';
|
||
statusBg = '#f8f9fa';
|
||
statusIcon = `
|
||
<svg width="140" height="140" viewBox="0 0 140 140" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||
<circle cx="70" cy="70" r="65" fill="#6c757d" fill-opacity="0.1" stroke="#6c757d" stroke-width="2"/>
|
||
<!-- Warehouse -->
|
||
<path d="M30 100V50L70 30L110 50V100H30Z" fill="#6c757d"/>
|
||
<path d="M40 100V60H60V100H40Z" fill="white"/>
|
||
<path d="M80 100V60H100V100H80Z" fill="white"/>
|
||
<path d="M70 30L110 50L120 45L70 20L20 45L30 50L70 30Z" fill="#495057"/>
|
||
<!-- Shalom Text -->
|
||
<text x="45" y="90" fill="white" font-family="Arial Black, sans-serif" font-weight="900" font-style="italic" font-size="8">SHALOM</text>
|
||
</svg>`;
|
||
} else {
|
||
statusIcon = `
|
||
<svg width="140" height="140" viewBox="0 0 140 140" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||
<circle cx="70" cy="70" r="65" fill="#0dcaf0" fill-opacity="0.1" stroke="#0dcaf0" stroke-width="2"/>
|
||
<!-- Box -->
|
||
<g transform="translate(40, 60)">
|
||
<path d="M0 10L30 20V50L0 40V10Z" fill="#e30613"/>
|
||
<path d="M30 20L60 10V40L30 50V20Z" fill="#b90510"/>
|
||
<path d="M0 10L30 0L60 10L30 20L0 10Z" fill="#f14b55"/>
|
||
<text x="5" y="35" fill="white" font-family="Arial Black, sans-serif" font-weight="900" font-style="italic" font-size="7" transform="skewY(15)">SHALOM</text>
|
||
</g>
|
||
</svg>`;
|
||
}
|
||
|
||
let html = `
|
||
<div id="status-capture-area" class="text-center mb-4 p-4" style="background: ${statusBg}; border-radius: 20px; border: 3px solid ${statusColor}; box-shadow: 0 10px 20px rgba(0,0,0,0.1);">
|
||
<div class="mb-3">${statusIcon}</div>
|
||
<h1 class="mt-2" style="color: ${statusColor}; font-weight: 900; text-transform: uppercase; letter-spacing: 1px;">${statusMessage}</h1>
|
||
<div class="badge bg-dark px-3 py-2 mt-2" style="font-size: 1rem;">Guía: ${orderNumber}</div>
|
||
<hr style="border-top: 2px dashed ${statusColor}; opacity: 0.3;">
|
||
<p class="mb-0" style="font-weight: bold; color: #555;">Destino: ${searchData.destino.nombre}</p>
|
||
<p class="text-muted small">Consulta realizada: ${new Date().toLocaleString('es-PE')}</p>
|
||
</div>
|
||
<div class="d-grid gap-2 mb-3">
|
||
<button class="btn btn-success" onclick="copyStatusToClipboard('${statusMessage}', '${orderNumber}', '${searchData.destino.nombre}')">
|
||
<i class="fab fa-whatsapp"></i> Copiar Resumen para Cliente
|
||
</button>
|
||
</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 (orderCode === '26') {
|
||
statusCell.innerHTML = '<span class="badge bg-info">OLVA COURIER</span>';
|
||
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);
|
||
}
|
||
});
|
||
|
||
function copyStatusToClipboard(status, order, destination) {
|
||
const text = `📦 *Estado de tu pedido Shalom*\n\n` +
|
||
`🔖 *Nro de Orden:* ${order}\n` +
|
||
`📍 *Destino:* ${destination}\n` +
|
||
`🚚 *Estado:* ${status}\n\n` +
|
||
`¡Tu pedido está en camino! Gracias por tu confianza. ✨`;
|
||
|
||
navigator.clipboard.writeText(text).then(() => {
|
||
alert('Resumen copiado al portapapeles. Ya puedes pegarlo en WhatsApp.');
|
||
}).catch(err => {
|
||
console.error('Error al copiar:', err);
|
||
});
|
||
}
|
||
</script>
|