34849-vm/completados.php
2026-02-12 03:37:54 +00:00

357 lines
17 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 WHERE estado = 'COMPLETADO ✅'";
if ($user_role === 'Asesor') {
$years_query .= " AND 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 = 'COMPLETADO ✅'";
$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.fecha_completado 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 Completados";
include 'layout_header.php';
?>
<div class="card mb-4">
<div class="card-body">
<form method="GET" action="completados.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($_GET['q'] ?? ''); ?>" 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="completados.php" class="btn btn-secondary">Limpiar</a>
</div>
</form>
</div>
</div>
<div class="card">
<div class="card-body">
<div class="table-responsive">
<table class="table table-striped">
<thead>
<tr>
<th>ID</th>
<th>Cliente</th>
<th>Celular</th>
<th>Producto</th>
<th>Monto Total</th>
<th>Monto Debe</th>
<th>Nro. Operación</th>
<th>Recojo Cliente (Día y Hora)</th>
<th>Estado</th>
<th>Asesor</th>
<th>Fecha Creación</th>
<th>Fecha Completado</th>
<th>Voucher Restante</th>
<th>Verificación de Pago</th>
<th>Acciones</th>
</tr>
</thead>
<tbody>
<?php if (empty($pedidos)): ?>
<tr>
<td colspan="15" class="text-center">No hay pedidos completados que coincidan con el filtro.</td>
</tr>
<?php else: ?>
<?php foreach ($pedidos as $pedido): ?>
<tr>
<td><?php echo htmlspecialchars($pedido['id']); ?></td>
<td><?php echo htmlspecialchars($pedido['nombre_completo']); ?></td>
<td><?php echo htmlspecialchars($pedido['celular']); ?></td>
<td><?php echo htmlspecialchars($pedido['producto']); ?></td>
<td><?php echo htmlspecialchars($pedido['monto_total']); ?></td>
<td><?php echo htmlspecialchars($pedido['monto_debe']); ?></td>
<td><?php echo htmlspecialchars($pedido['numero_operacion'] ?? 'N/A'); ?></td>
<td <?php if (in_array($user_role, ['Administrador', 'personal', 'Verificador de Pagos']) || strpos($user_role, 'Asesor') !== false) { echo 'class="editable-recojo" data-id="'.$pedido['id'].'" title="Doble clic para editar"'; } ?>>
<?php echo !empty($pedido['fecha_recojo']) ? htmlspecialchars($pedido['fecha_recojo']) : '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><?php echo htmlspecialchars($pedido['asesor_nombre'] ?? 'N/A'); ?></td>
<td><?php echo htmlspecialchars($pedido['created_at']); ?></td>
<td><?php
if (!empty($pedido['fecha_completado'])) {
try {
// Create DateTime object directly, assuming server timezone is correct
$date = new DateTime($pedido['fecha_completado']);
// Format to d/m/Y H:i:s
echo htmlspecialchars($date->format('d/m/Y H:i:s'));
} catch (Exception $e) {
// Fallback for invalid date formats, which is the likely issue
echo htmlspecialchars($pedido['fecha_completado']);
}
} else {
echo 'N/A';
}
?></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>
<?php
$estado_pago_class = '';
if (isset($pedido['estado_pago'])) {
if ($pedido['estado_pago'] == 'Pendiente a verificación') {
$estado_pago_class = 'estado-pago-pendiente';
} elseif ($pedido['estado_pago'] == 'Verificado') {
$estado_pago_class = 'estado-pago-verificado';
}
}
?>
<span class="badge <?php echo $estado_pago_class; ?>">
<?php if (in_array($user_role, ['Administrador', 'Verificador de Pagos'])): ?>
<select class="form-select-pago" onchange="updateEstadoPago(<?php echo $pedido['id']; ?>, this)">
<option value="Pendiente a verificación" <?php echo ($pedido['estado_pago'] == 'Pendiente a verificación') ? 'selected' : ''; ?>>Pendiente a verificación</option>
<option value="Verificado" <?php echo ($pedido['estado_pago'] == 'Verificado') ? 'selected' : ''; ?>>Verificado</option>
</select>
<?php else: ?>
<?php echo htmlspecialchars($pedido['estado_pago']); ?>
<?php endif; ?>
</span>
</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; ?>
<?php endif; ?>
</tbody>
</table>
</div>
</div>
</div>
<script>
function updateEstadoPago(pedidoId, selectElement) {
const estado = selectElement.value;
const badge = selectElement.closest('.badge');
// Guardar el estado original en caso de error
const originalState = Array.from(selectElement.options).find(opt => opt.defaultSelected).value;
const formData = new URLSearchParams();
formData.append('pedido_id', pedidoId);
formData.append('estado_pago', estado);
fetch('update_pago.php', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: formData
})
.then(response => response.json())
.then(data => {
if (data.success) {
console.log('Estado de pago actualizado con éxito.');
// Actualizar color del badge dinámicamente
badge.classList.remove('estado-pago-pendiente', 'estado-pago-verificado');
if (estado === 'Pendiente a verificación') {
badge.classList.add('estado-pago-pendiente');
} else if (estado === 'Verificado') {
badge.classList.add('estado-pago-verificado');
}
// Actualizar el estado 'selected' del <select>
Array.from(selectElement.options).forEach(opt => {
opt.defaultSelected = (opt.value === estado);
});
} else {
alert('Error: ' + (data.message || 'No se pudo actualizar el estado.'));
// Revertir el <select> al estado original
selectElement.value = originalState;
}
})
.catch(error => {
console.error('Error:', error);
alert('Hubo un error de conexión al intentar actualizar el estado.');
// Revertir el <select> al estado original
selectElement.value = originalState;
});
}
document.addEventListener('DOMContentLoaded', function() {
const userRole = "<?php echo $user_role; ?>";
const authorizedRoles = ['Administrador', 'personal', 'Verificador de Pagos'];
if (authorizedRoles.includes(userRole) || userRole.includes('Asesor')) {
const table = document.querySelector('.table');
table.addEventListener('dblclick', function(e) {
const cell = e.target.closest('.editable-recojo');
if (!cell) return;
// Evitar doble edición si ya hay un input
if (cell.querySelector('input')) {
return;
}
const originalText = cell.textContent.trim() === 'N/A' ? '' : cell.textContent.trim();
const pedidoId = cell.dataset.id;
cell.innerHTML = `<input type="text" class="form-control form-control-sm" value="${originalText}">`;
const input = cell.querySelector('input');
input.focus();
const saveChanges = function() {
const newValue = input.value.trim();
// Reemplazar el input con el texto
cell.innerHTML = newValue === '' ? 'N/A' : newValue;
// Si el valor no ha cambiado, no hacer nada
if (newValue === originalText) {
return;
}
const formData = new URLSearchParams();
formData.append('id', pedidoId);
formData.append('fecha_recojo', newValue);
fetch('update_recojo.php', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: formData
})
.then(response => response.json())
.then(data => {
if (!data.success) {
console.error('Error al guardar:', data.message);
cell.innerHTML = originalText === '' ? 'N/A' : originalText; // Revertir en caso de error
alert('No se pudo guardar el cambio. Por favor, inténtalo de nuevo.');
}
})
.catch(error => {
console.error('Error de red:', error);
cell.innerHTML = originalText === '' ? 'N/A' : originalText; // Revertir en caso de error
alert('Error de conexión. No se pudo guardar el cambio.');
});
};
input.addEventListener('blur', saveChanges);
input.addEventListener('keydown', function(e) {
if (e.key === 'Enter') {
input.blur(); // Dispara el evento blur para guardar
} else if (e.key === 'Escape') {
input.removeEventListener('blur', saveChanges); // Evitar que se guarde
cell.innerHTML = originalText === '' ? 'N/A' : originalText;
}
});
});
}
});
</script>
<?php include 'layout_footer.php'; ?>