34849-vm/flujo_de_caja.php
2026-02-03 06:08:39 +00:00

203 lines
7.9 KiB
PHP

<?php
require_once 'layout_header.php';
require_once 'db/config.php';
$month = isset($_GET['month']) ? $_GET['month'] : date('m');
$year = isset($_GET['year']) ? $_GET['year'] : date('Y');
$start_date = "$year-$month-01";
$days_in_month = cal_days_in_month(CAL_GREGORIAN, $month, $year);
$end_date = "$year-$month-$days_in_month";
$flujo_data = [];
try {
$pdo = db();
$stmt = $pdo->prepare("SELECT * FROM flujo_caja WHERE fecha BETWEEN ? AND ?");
$stmt->execute([$start_date, $end_date]);
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
foreach ($rows as $row) {
$flujo_data[$row['fecha']] = $row;
}
} catch (PDOException $e) {
// Handle error
}
$columns = [
'bcp_yape', 'b_nacion', 'interbank', 'bbva', 'otros_ingresos',
'tu1', 'tu2', 'tu3', 'fl1', 'fl2', 'fl3',
'rc_envio', 'rc_contraent'
];
?>
<style>
.table thead th {
background-color: #e9ecef; /* Un gris claro y profesional */
color: #495057;
font-weight: 600;
}
.table td[contenteditable="true"]:focus {
background-color: #fff3cd; /* Un amarillo suave para resaltar la celda activa */
}
</style>
<div class="container-fluid mt-4">
<h2>Flujo de Caja</h2>
<p>Registro y control de los movimientos de ingresos y gastos.</p>
<form method="GET" action="flujo_de_caja.php" class="form-inline mb-4">
<div class="form-group mr-2">
<label for="month" class="mr-2">Mes:</label>
<select name="month" id="month" class="form-control">
<?php for ($m = 1; $m <= 12; $m++): ?>
<option value="<?php echo str_pad($m, 2, '0', STR_PAD_LEFT); ?>" <?php echo $m == $month ? 'selected' : ''; ?>>
<?php echo DateTime::createFromFormat('!m', $m)->format('F'); ?>
</option>
<?php endfor; ?>
</select>
</div>
<div class="form-group mr-2">
<label for="year" class="mr-2">Año:</label>
<select name="year" id="year" class="form-control">
<?php for ($y = date('Y'); $y >= date('Y') - 5; $y--): ?>
<option value="<?php echo $y; ?>" <?php echo $y == $year ? 'selected' : ''; ?>><?php echo $y; ?></option>
<?php endfor; ?>
</select>
</div>
<button type="submit" class="btn btn-primary">Filtrar</button>
</form>
<div class="table-responsive">
<table class="table table-bordered table-striped table-hover" style="width: 100%;">
<thead>
<tr>
<th rowspan="2" style="vertical-align: middle; text-align: center;">Fecha</th>
<th colspan="5" style="text-align: center;">Ingresos</th>
<th colspan="6" style="text-align: center;">Inversion Publicitaria</th>
<th rowspan="2" style="vertical-align: middle; text-align: center;">RC ENVIO</th>
<th rowspan="2" style="vertical-align: middle; text-align: center;">RC CONTRAENT</th>
<th rowspan="2" style="vertical-align: middle; text-align: center;">Total Ingresos</th>
<th rowspan="2" style="vertical-align: middle; text-align: center;">Total Inversion Publicitaria</th>
<th rowspan="2" style="vertical-align: middle; text-align: center;">Recaudo final</th>
</tr>
<tr>
<th>BCP/YAPE</th>
<th>B. NACION</th>
<th>INTERBANK</th>
<th>BBVA</th>
<th>Otros Ingresos</th>
<th>TU 1</th>
<th>TU 2</th>
<th>TU 3</th>
<th>FL1</th>
<th>FL2</th>
<th>FL3</th>
</tr>
</thead>
<tbody>
<?php for ($day = 1; $day <= $days_in_month; $day++):
$date = date('Y-m-d', strtotime("$year-$month-$day"));
$day_data = isset($flujo_data[$date]) ? $flujo_data[$date] : array_fill_keys($columns, '0.00');
?>
<tr data-date="<?php echo $date; ?>">
<td><?php echo $date; ?></td>
<?php foreach ($columns as $col): ?>
<td contenteditable="true" data-column="<?php echo $col; ?>"><?php echo htmlspecialchars($day_data[$col]); ?></td>
<?php endforeach; ?>
<td class="total-ingresos">0.00</td>
<td class="total-inversion">0.00</td>
<td class="recaudo-final">0.00</td>
</tr>
<?php endfor; ?>
</tbody>
</table>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
const table = document.querySelector('.table');
// Function to update totals for a specific row
function updateTotals(row) {
const getVal = (selector) => {
const cell = row.querySelector(`[data-column="${selector}"]`);
return parseFloat(cell.textContent) || 0;
};
const ingresos = getVal('bcp_yape') + getVal('b_nacion') + getVal('interbank') + getVal('bbva') + getVal('otros_ingresos') + getVal('rc_envio') + getVal('rc_contraent');
const totalInversion = getVal('tu1') + getVal('tu2') + getVal('tu3') + getVal('fl1') + getVal('fl2') + getVal('fl3');
const recaudoFinal = ingresos - totalInversion;
row.querySelector('.total-ingresos').textContent = ingresos.toFixed(2);
row.querySelector('.total-inversion').textContent = totalInversion.toFixed(2);
row.querySelector('.recaudo-final').textContent = recaudoFinal.toFixed(2);
}
// Initial calculation for all rows
table.querySelectorAll('tbody tr').forEach(updateTotals);
// Event listener for cell focus to select all content
table.addEventListener('focus', function(e) {
if (e.target.hasAttribute('contenteditable')) {
const range = document.createRange();
range.selectNodeContents(e.target);
const sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
}
}, true); // Use capturing for focus
// Event listener for cell edits
table.addEventListener('blur', function(e) {
if (e.target.hasAttribute('contenteditable')) {
const cell = e.target;
const row = cell.closest('tr');
const date = row.dataset.date;
const column = cell.dataset.column;
let value = parseFloat(cell.textContent);
if (isNaN(value)) {
value = 0;
cell.textContent = '0.00';
}
cell.textContent = value.toFixed(2);
// Save data to server
fetch('save_flujo_caja.php', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ fecha: date, columna: column, valor: value })
})
.then(response => response.json())
.then(data => {
if (!data.success) {
console.error('Error saving data:', data.message);
// Optional: Add user feedback for save failure
}
})
.catch(error => console.error('Fetch error:', error));
// Update totals for the edited row
updateTotals(row);
}
}, true); // Use capturing to ensure blur event is handled properly
// Event listener for Enter key to save and not expand
table.addEventListener('keydown', function(e) {
if (e.key === 'Enter' && e.target.hasAttribute('contenteditable')) {
e.preventDefault(); // Prevent new line
e.target.blur(); // Trigger blur to save
}
});
});
</script>
<?php
require_once 'layout_footer.php';
?>