Mejorar Balance General con detalle de conceptos especiales y filtro por año

This commit is contained in:
Administrador Ibiza
2025-12-30 23:36:51 -06:00
parent d629526485
commit 5e714ebae9
4 changed files with 327 additions and 32 deletions

View File

@@ -521,6 +521,60 @@ function exportConceptsCSV() {
</script>
<?php else: ?>
<div class="card mb-4">
<div class="card-header d-flex justify-content-between align-items-center">
<h5 class="card-title mb-0">
<i class="bi bi-funnel"></i> Filtro por Año
</h5>
<button type="button" class="btn btn-sm btn-outline-secondary" data-bs-toggle="collapse" data-bs-target="#yearFilterCollapse">
<i class="bi bi-chevron-down"></i>
</button>
</div>
<div class="collapse show" id="yearFilterCollapse">
<div class="card-body">
<form id="yearFilter">
<div class="row g-3">
<div class="col-md-3">
<label class="form-label">Año</label>
<select name="filter_year" class="form-select">
<option value="">Todos los años</option>
<?php
$years = range(2024, date('Y') + 1);
foreach ($years as $y): ?>
<option value="<?= $y ?>" <?= ($_GET['filter_year'] ?? '') == $y ? 'selected' : '' ?>><?= $y ?></option>
<?php endforeach; ?>
</select>
</div>
</div>
<div class="row mt-3">
<div class="col-12">
<button type="submit" class="btn btn-primary">
<i class="bi bi-search"></i> Aplicar Filtro
</button>
<a href="/dashboard.php?page=reportes" class="btn btn-outline-secondary">
<i class="bi bi-x-circle"></i> Limpiar Filtro
</a>
</div>
</div>
</form>
</div>
</div>
</div>
<script>
document.getElementById('yearFilter').addEventListener('submit', function(e) {
e.preventDefault();
const formData = new FormData(this);
const params = new URLSearchParams();
if (formData.get('filter_year')) {
params.append('filter_year', formData.get('filter_year'));
}
window.location.href = '/dashboard.php?page=reportes&' + params.toString();
});
</script>
<div class="row g-4 mb-4">
<div class="col-md-3">
@@ -596,33 +650,75 @@ function exportConceptsCSV() {
</div>
</div>
<?php endif; ?>
<div class="col-md-<?= Auth::isLector() ? '12' : '6' ?>">
<div class="col-md-<?= Auth::isLector() ? '12' : '12' ?>">
<div class="card">
<div class="card-header d-flex justify-content-between align-items-center">
<h5 class="card-title mb-0">Resumen Financiero</h5>
<h5 class="card-title mb-0">
Resumen Financiero
<?php if (!empty($conceptDetails['year'])): ?>
<small class="text-muted">(<?= $conceptDetails['year'] ?>)</small>
<?php endif; ?>
</h5>
<button onclick="exportBalancePDF()" class="btn btn-outline-primary btn-sm">
<i class="bi bi-file-earmark-pdf"></i> PDF
</button>
</div>
<div class="card-body">
<table class="table table-sm">
<tr>
<td>Total Ingresos (Conceptos):</td>
<td class="text-end text-success">$<?= number_format($balance['total_incomes'], 2) ?></td>
</tr>
<?php if (!Auth::isLector()): ?>
<tr class="table-light">
<td>Total Egresos:</td>
<td class="text-end text-danger">$<?= number_format($balance['total_expenses'], 2) ?></td>
</tr>
<tr class="table-dark">
<td><strong>Balance:</strong></td>
<td class="text-end fw-bold <?= $balance['balance'] >= 0 ? 'text-success' : 'text-danger' ?>">
$<?= number_format($balance['balance'], 2) ?>
</td>
</tr>
<?php endif; ?>
</table>
<?php if (empty($conceptDetails['concepts'])): ?>
<p class="text-muted">No hay conceptos especiales registrados para el año seleccionado.</p>
<?php else: ?>
<table class="table table-sm table-bordered">
<thead class="table-primary">
<tr>
<th>Concepto</th>
<th class="text-end">Esperado</th>
<th class="text-end">Recaudado</th>
<th class="text-end">Pendiente</th>
<th class="text-end">Gastos Asociados</th>
<th class="text-end">Balance</th>
</tr>
</thead>
<tbody>
<?php foreach ($conceptDetails['concepts'] as $cd): ?>
<tr>
<td>
<strong><?= htmlspecialchars($cd['concept']['name']) ?></strong>
<?php if (!empty($cd['concept']['description'])): ?>
<small class="text-muted d-block"><?= htmlspecialchars($cd['concept']['description']) ?></small>
<?php endif; ?>
</td>
<td class="text-end">$<?= number_format($cd['expected'], 2) ?></td>
<td class="text-end text-success">$<?= number_format($cd['collected'], 2) ?></td>
<td class="text-end text-warning">$<?= number_format($cd['pending'], 2) ?></td>
<?php if (!Auth::isLector()): ?>
<td class="text-end text-danger">$<?= number_format($cd['expenses'], 2) ?></td>
<td class="text-end fw-bold <?= $cd['balance'] >= 0 ? 'text-success' : 'text-danger' ?>">
$<?= number_format($cd['balance'], 2) ?>
</td>
<?php else: ?>
<td class="text-end" colspan="2">-</td>
<?php endif; ?>
</tr>
<?php endforeach; ?>
</tbody>
<tfoot class="table-dark">
<tr>
<th><strong>TOTALES:</strong></th>
<th class="text-end">$<?= number_format($conceptDetails['totals']['expected'], 2) ?></th>
<th class="text-end">$<?= number_format($conceptDetails['totals']['collected'], 2) ?></th>
<th class="text-end">$<?= number_format($conceptDetails['totals']['pending'], 2) ?></th>
<?php if (!Auth::isLector()): ?>
<th class="text-end">$<?= number_format($conceptDetails['totals']['expenses'], 2) ?></th>
<th class="text-end fw-bold <?= $conceptDetails['totals']['balance'] >= 0 ? 'text-success' : 'text-danger' ?>">
$<?= number_format($conceptDetails['totals']['balance'], 2) ?>
</th>
<?php else: ?>
<th class="text-end" colspan="2">-</th>
<?php endif; ?>
</tr>
</tfoot>
</table>
<?php endif; ?>
</div>
</div>
</div>
@@ -666,11 +762,21 @@ function exportConceptsCSV() {
<script>
function exportBalancePDF() {
window.open('/dashboard.php?page=reportes_actions&action=export_pdf_report&type=balance', '_blank');
const filterYear = '<?= $_GET['filter_year'] ?? '' ?>';
let url = '/dashboard.php?page=reportes_actions&action=export_pdf_report&type=balance';
if (filterYear) {
url += '&filter_year=' + filterYear;
}
window.open(url, '_blank');
}
function exportBalanceCSV() {
window.open('/dashboard.php?page=reportes_actions&action=export_csv_balance', '_blank');
const filterYear = '<?= $_GET['filter_year'] ?? '' ?>';
let url = '/dashboard.php?page=reportes_actions&action=export_csv_balance';
if (filterYear) {
url += '&filter_year=' + filterYear;
}
window.open(url, '_blank');
}
function exportExpensesPDF() {