34849-vm/operaciones_provincia.php
2026-04-21 19:26:12 +00:00

294 lines
12 KiB
PHP

<?php
session_start();
if (!isset($_SESSION['user_id'])) {
header('Location: login.php');
exit;
}
$user_role = $_SESSION['user_role'] ?? '';
if ($user_role !== 'Administrador' && $user_role !== 'admin') {
header('Location: dashboard.php');
exit;
}
require_once 'db/config.php';
$pageTitle = "Operaciones De provincia";
include 'layout_header.php';
$pdo = db();
// Filter by date
$selected_date = $_GET['fecha'] ?? date('Y-m-d');
// Fetch data from DB for the selected date
$operaciones = [];
$total_recaudacion = 0;
try {
$stmt = $pdo->prepare("SELECT * FROM operaciones_provincia WHERE DATE(fecha_completado) = ? ORDER BY fecha_completado DESC");
$stmt->execute([$selected_date]);
$operaciones = $stmt->fetchAll(PDO::FETCH_ASSOC);
foreach ($operaciones as $op) {
$total_recaudacion += (float)($op['monto_debe'] ?? 0);
}
} catch (PDOException $e) {
// Handle error
}
?>
<style>
.table thead th {
background-color: #337ab7;
color: #ffffff;
font-weight: 600;
position: sticky;
top: 0;
z-index: 10;
}
.table td[contenteditable="true"]:focus {
background-color: #fff3cd;
outline: 2px solid #337ab7;
}
.btn-add {
margin-bottom: 15px;
}
.summary-card {
background: linear-gradient(135deg, #198754 0%, #146c43 100%);
color: white;
border: none;
border-radius: 15px;
box-shadow: 0 4px 15px rgba(0,0,0,0.1);
}
</style>
<div class="container-fluid mt-4">
<div class="d-flex justify-content-between align-items-center mb-4">
<h2>Operaciones De provincia</h2>
<div class="d-flex gap-3 align-items-center">
<form method="GET" class="d-flex align-items-center gap-2">
<label for="fecha" class="mb-0 fw-bold">Fecha:</label>
<input type="date" name="fecha" id="fecha" class="form-control" value="<?php echo $selected_date; ?>" onchange="this.form.submit()">
</form>
<button id="addRow" class="btn btn-success">
<i class="fas fa-plus"></i> Agregar Fila
</button>
</div>
</div>
<div class="row mb-4">
<div class="col-md-4">
<div class="card summary-card">
<div class="card-body">
<h5 class="card-title opacity-75">Recaudación del Día</h5>
<h2 class="mb-0 fw-bold">S/ <?php echo number_format($total_recaudacion, 2); ?></h2>
<p class="mb-0 mt-2 small opacity-75">
<i class="fas fa-calendar-alt me-1"></i>
<?php echo date('d/m/Y', strtotime($selected_date)); ?>
</p>
</div>
</div>
</div>
</div>
<div class="card shadow-sm">
<div class="card-body p-0">
<div class="table-responsive" style="max-height: 65vh; overflow-y: auto;">
<table class="table table-bordered table-striped table-hover mb-0" id="operacionesTable">
<thead>
<tr>
<th>ID</th>
<th>Cliente</th>
<th>Celular</th>
<th>Producto</th>
<th>Monto Total</th>
<th>Monto que debe</th>
<th>Nro. Operación</th>
<th>Banco</th>
<th>Fecha Completado</th>
<th>Acciones</th>
</tr>
</thead>
<tbody>
<?php if (empty($operaciones)): ?>
<tr class="no-data">
<td colspan="10" class="text-center py-4 text-muted">No hay operaciones registradas para esta fecha.</td>
</tr>
<?php else: ?>
<?php foreach ($operaciones as $op): ?>
<tr data-id="<?php echo $op['id']; ?>">
<td><?php echo $op['id']; ?></td>
<td contenteditable="true" data-column="cliente"><?php echo htmlspecialchars($op['cliente'] ?? ''); ?></td>
<td contenteditable="true" data-column="celular"><?php echo htmlspecialchars($op['celular'] ?? ''); ?></td>
<td contenteditable="true" data-column="producto"><?php echo htmlspecialchars($op['producto'] ?? ''); ?></td>
<td contenteditable="true" data-column="monto_total"><?php echo htmlspecialchars($op['monto_total'] ?? '0.00'); ?></td>
<td contenteditable="true" data-column="monto_debe"><?php echo htmlspecialchars($op['monto_debe'] ?? '0.00'); ?></td>
<td contenteditable="true" data-column="nro_operacion"><?php echo htmlspecialchars($op['nro_operacion'] ?? ''); ?></td>
<td contenteditable="true" data-column="banco"><?php echo htmlspecialchars($op['banco'] ?? ''); ?></td>
<td contenteditable="true" data-column="fecha_completado"><?php
if (!empty($op['fecha_completado'])) {
try {
$date = new DateTime($op['fecha_completado']);
echo htmlspecialchars($date->format('d/m/Y H:i:s'));
} catch (Exception $e) {
echo htmlspecialchars($op['fecha_completado']);
}
}
?></td>
<td class="text-center">
<button class="btn btn-outline-danger btn-sm delete-row">
<i class="fas fa-trash"></i>
</button>
</td>
</tr>
<?php endforeach; ?>
<?php endif; ?>
</tbody>
</table>
</div>
</div>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
const table = document.getElementById('operacionesTable');
const tbody = table.querySelector('tbody');
const addRowBtn = document.getElementById('addRow');
const selectedDate = "<?php echo $selected_date; ?>";
function updateSummary() {
let total = 0;
table.querySelectorAll('tbody tr:not(.no-data)').forEach(row => {
const val = parseFloat(row.querySelector('[data-column="monto_debe"]').textContent.replace(/[^0-9.-]/g, '')) || 0;
total += val;
});
document.querySelector('.summary-card h2').textContent = 'S/ ' + total.toLocaleString('en-US', {minimumFractionDigits: 2, maximumFractionDigits: 2});
}
// Add new row
addRowBtn.addEventListener('click', function() {
const noDataRow = tbody.querySelector('.no-data');
if (noDataRow) noDataRow.remove();
const now = new Date();
const day = String(now.getDate()).padStart(2, '0');
const month = String(now.getMonth() + 1).padStart(2, '0');
const year = now.getFullYear();
const hours = String(now.getHours()).padStart(2, '0');
const minutes = String(now.getMinutes()).padStart(2, '0');
const seconds = String(now.getSeconds()).padStart(2, '0');
const currentDateTime = `${day}/${month}/${year} ${hours}:${minutes}:${seconds}`;
fetch('save_operaciones_provincia.php', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ action: 'create' })
})
.then(response => response.json())
.then(data => {
if (data.success) {
const tr = document.createElement('tr');
tr.dataset.id = data.id;
tr.innerHTML = `
<td>${data.id}</td>
<td contenteditable="true" data-column="cliente"></td>
<td contenteditable="true" data-column="celular"></td>
<td contenteditable="true" data-column="producto"></td>
<td contenteditable="true" data-column="monto_total">0.00</td>
<td contenteditable="true" data-column="monto_debe">0.00</td>
<td contenteditable="true" data-column="nro_operacion"></td>
<td contenteditable="true" data-column="banco"></td>
<td contenteditable="true" data-column="fecha_completado">${currentDateTime}</td>
<td class="text-center">
<button class="btn btn-outline-danger btn-sm delete-row">
<i class="fas fa-trash"></i>
</button>
</td>
`;
tbody.insertBefore(tr, tbody.firstChild);
// Set initial date
fetch('save_operaciones_provincia.php', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ action: 'update', id: data.id, column: 'fecha_completado', value: currentDateTime })
});
tr.querySelector('[data-column="cliente"]').focus();
}
});
});
// Edit cell
table.addEventListener('blur', function(e) {
if (e.target.hasAttribute('contenteditable')) {
const cell = e.target;
const row = cell.closest('tr');
const id = row.dataset.id;
const column = cell.dataset.column;
let value = cell.textContent.trim();
// Basic numeric formatting for monto columns
if (column === 'monto_total' || column === 'monto_debe') {
let num = parseFloat(value.replace(/[^0-9.-]/g, ''));
if (isNaN(num)) num = 0;
value = num.toFixed(2);
cell.textContent = value;
updateSummary();
}
fetch('save_operaciones_provincia.php', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ action: 'update', id: id, column: column, value: value })
})
.then(response => response.json())
.then(data => {
if (!data.success) {
alert('Error al guardar: ' + data.message);
}
});
}
}, true);
// Delete row
table.addEventListener('click', function(e) {
if (e.target.closest('.delete-row')) {
if (confirm('¿Estás seguro de eliminar esta fila?')) {
const row = e.target.closest('tr');
const id = row.dataset.id;
fetch('save_operaciones_provincia.php', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ action: 'delete', id: id })
})
.then(response => response.json())
.then(data => {
if (data.success) {
row.remove();
updateSummary();
if (tbody.children.length === 0) {
tbody.innerHTML = '<tr class="no-data"><td colspan="10" class="text-center py-4 text-muted">No hay operaciones registradas para esta fecha.</td></tr>';
}
} else {
alert('Error al eliminar: ' + data.message);
}
});
}
}
});
// Handle Enter key
table.addEventListener('keydown', function(e) {
if (e.key === 'Enter' && e.target.hasAttribute('contenteditable')) {
e.preventDefault();
e.target.blur();
}
});
});
</script>
<?php include 'layout_footer.php'; ?>