297 lines
12 KiB
PHP
297 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>Asesor</th>
|
|
<th>Acciones</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<?php if (empty($operaciones)): ?>
|
|
<tr class="no-data">
|
|
<td colspan="11" 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 contenteditable="true" data-column="asesor"><?php echo htmlspecialchars($op['asesor'] ?? ''); ?></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 contenteditable="true" data-column="asesor"></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="11" 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'; ?>
|