34849-vm/liquidaciones_provincia.php
2026-02-20 17:09:19 +00:00

210 lines
8.0 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');
$days_in_month = cal_days_in_month(CAL_GREGORIAN, $month, $year);
$provincias = ['LIMA', 'AREQUIPA', 'TRUJILLO', 'ICA', 'CUSCO', 'CAJAMARCA', 'CHICLAYO', 'PIURA'];
// Fetch data for the month
$pdo = db();
$stmt = $pdo->prepare("SELECT fecha, provincia, monto, estado FROM liquidaciones_provincia WHERE MONTH(fecha) = ? AND YEAR(fecha) = ?");
$stmt->execute([$month, $year]);
$data = $stmt->fetchAll(PDO::FETCH_ASSOC);
// Organize data for easy access
$liquidaciones = [];
foreach ($data as $row) {
$liquidaciones[$row['fecha']][$row['provincia']] = [
'monto' => $row['monto'],
'estado' => $row['estado']
];
}
?>
<style>
.table thead th {
background-color: #337ab7;
color: #ffffff;
font-weight: 600;
position: sticky;
top: 0;
z-index: 10;
}
.table tfoot th {
position: sticky;
bottom: 0;
background-color: #e9ecef;
z-index: 10;
font-weight: 700;
}
.table td[contenteditable="true"]:focus {
background-color: #fff3cd;
}
</style>
<div class="container-fluid mt-4">
<h2>Liquidaciones Provincia</h2>
<p>Tabla de liquidaciones por provincia para el mes seleccionado.</p>
<form method="GET" action="liquidaciones_provincia.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" style="max-height: 70vh; overflow-y: auto;">
<table class="table table-bordered table-striped table-hover" style="width: 100%;">
<thead>
<tr>
<th>Fecha</th>
<?php foreach ($provincias as $provincia): ?>
<th><?php echo htmlspecialchars($provincia); ?></th>
<th>ESTADO</th>
<?php endforeach; ?>
</tr>
</thead>
<tbody>
<?php for ($day = 1; $day <= $days_in_month; $day++): ?>
<?php $date = date('Y-m-d', strtotime("$year-$month-$day")); ?>
<tr data-date="<?php echo $date; ?>">
<td><?php echo $date; ?></td>
<?php foreach ($provincias as $provincia): ?>
<?php
$monto = isset($liquidaciones[$date][$provincia]['monto']) ? number_format($liquidaciones[$date][$provincia]['monto'], 2, '.', '') : '0.00';
$estado = isset($liquidaciones[$date][$provincia]['estado']) ? htmlspecialchars($liquidaciones[$date][$provincia]['estado']) : '';
?>
<td class="editable-cell" contenteditable="true" data-provincia="<?php echo htmlspecialchars($provincia); ?>" data-column="monto"><?php echo $monto; ?></td>
<td class="editable-cell" contenteditable="true" data-provincia="<?php echo htmlspecialchars($provincia); ?>" data-column="estado"><?php echo $estado; ?></td>
<?php endforeach; ?>
</tr>
<?php endfor; ?>
</tbody>
<tfoot>
<tr>
<th>TOTAL</th>
<?php foreach ($provincias as $provincia): ?>
<th data-total-column="<?php echo htmlspecialchars($provincia); ?>">0.00</th>
<th></th>
<?php endforeach; ?>
</tr>
</tfoot>
</table>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
const table = document.querySelector('.table');
function calculateTotals() {
const totals = {};
<?php foreach ($provincias as $provincia): ?>
totals['<?php echo $provincia; ?>'] = 0;
<?php endforeach; ?>
table.querySelectorAll('tbody tr').forEach(row => {
<?php foreach ($provincias as $provincia): ?>
const cell = row.querySelector(`td[data-provincia="<?php echo $provincia; ?>"][data-column="monto"]`);
if (cell) {
const value = parseFloat(cell.textContent.replace(/,/g, '')) || 0;
totals['<?php echo $provincia; ?>'] += value;
}
<?php endforeach; ?>
});
<?php foreach ($provincias as $provincia): ?>
const totalCell = table.querySelector(`tfoot th[data-total-column="<?php echo $provincia; ?>"]`);
if (totalCell) {
totalCell.textContent = totals['<?php echo $provincia; ?>'].toFixed(2);
}
<?php endforeach; ?>
}
// Initial calculation
calculateTotals();
table.addEventListener('keydown', function(e) {
if (e.key === 'Enter' && e.target.classList.contains('editable-cell')) {
e.preventDefault();
e.target.blur(); // Trigger blur to save
}
});
table.addEventListener('blur', function(e) {
if (e.target.classList.contains('editable-cell')) {
const cell = e.target;
const row = cell.closest('tr');
const fecha = row.dataset.date;
const provincia = cell.dataset.provincia;
const columna = cell.dataset.column;
let valor = cell.textContent.trim();
if (columna === 'monto') {
let numValue = parseFloat(valor.replace(/,/g, ''));
if (isNaN(numValue)) {
numValue = 0;
}
valor = numValue;
// Format back to 2 decimal places for display
cell.textContent = numValue.toFixed(2);
}
const data = { fecha, provincia, columna, valor };
fetch('save_liquidaciones_provincia.php', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data)
})
.then(response => response.json())
.then(result => {
if (result.success) {
if (columna === 'monto') {
calculateTotals();
}
} else {
console.error('Failed to save:', result.message);
// alert('Error al guardar el dato.'); // Optional: notify user
}
})
.catch(error => console.error('Error:', error));
}
}, true); // Use capturing to ensure blur event is handled reliably
table.addEventListener('focus', function(e) {
if (e.target.classList.contains('editable-cell')) {
// Select all text in cell on focus
const selection = window.getSelection();
const range = document.createRange();
range.selectNodeContents(e.target);
selection.removeAllRanges();
selection.addRange(range);
}
}, true);
});
</script>
<?php
require_once 'layout_footer.php';
?>