reportes
This commit is contained in:
@@ -0,0 +1,127 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* API: Reporte de pagos recibidos en domicilios.
|
||||||
|
*
|
||||||
|
* GET params:
|
||||||
|
* modo 'dia' | 'mes' | 'rango' (default: 'dia')
|
||||||
|
* fecha YYYY-MM-DD (para modo=dia)
|
||||||
|
* anio año 4 dígitos (para modo=mes)
|
||||||
|
* mes 1-12 (para modo=mes)
|
||||||
|
* desde YYYY-MM-DD (para modo=rango)
|
||||||
|
* hasta YYYY-MM-DD (para modo=rango)
|
||||||
|
* enfermera_id INT (opcional)
|
||||||
|
*/
|
||||||
|
require_once __DIR__ . '/../../config/config.php';
|
||||||
|
require_once __DIR__ . '/../../classes/Database.php';
|
||||||
|
|
||||||
|
header('Content-Type: application/json; charset=utf-8');
|
||||||
|
header('X-Content-Type-Options: nosniff');
|
||||||
|
|
||||||
|
requireAuthentication();
|
||||||
|
|
||||||
|
$db = Database::getInstance();
|
||||||
|
$modo = in_array($_GET['modo'] ?? '', ['dia','mes','rango']) ? $_GET['modo'] : 'dia';
|
||||||
|
|
||||||
|
$wheres = [];
|
||||||
|
$params = [];
|
||||||
|
|
||||||
|
switch ($modo) {
|
||||||
|
|
||||||
|
case 'mes':
|
||||||
|
$anio = isset($_GET['anio']) && ctype_digit($_GET['anio']) ? (int)$_GET['anio'] : (int)date('Y');
|
||||||
|
$mes = isset($_GET['mes']) && ctype_digit($_GET['mes']) ? (int)$_GET['mes'] : (int)date('n');
|
||||||
|
if ($mes < 1 || $mes > 12) $mes = (int)date('n');
|
||||||
|
$wheres[] = 'YEAR(d.fecha_programada) = ?';
|
||||||
|
$params[] = $anio;
|
||||||
|
$wheres[] = 'MONTH(d.fecha_programada) = ?';
|
||||||
|
$params[] = $mes;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'rango':
|
||||||
|
$desde = $_GET['desde'] ?? date('Y-m-01');
|
||||||
|
$hasta = $_GET['hasta'] ?? date('Y-m-d');
|
||||||
|
if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $desde)) $desde = date('Y-m-01');
|
||||||
|
if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $hasta)) $hasta = date('Y-m-d');
|
||||||
|
$wheres[] = 'DATE(d.fecha_programada) BETWEEN ? AND ?';
|
||||||
|
$params[] = $desde;
|
||||||
|
$params[] = $hasta;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default: // dia
|
||||||
|
$fecha = $_GET['fecha'] ?? date('Y-m-d');
|
||||||
|
if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $fecha)) $fecha = date('Y-m-d');
|
||||||
|
$wheres[] = 'DATE(d.fecha_programada) = ?';
|
||||||
|
$params[] = $fecha;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filtro por enfermera
|
||||||
|
$enfermeraId = null;
|
||||||
|
if (!empty($_GET['enfermera_id']) && ctype_digit($_GET['enfermera_id'])) {
|
||||||
|
$enfermeraId = (int)$_GET['enfermera_id'];
|
||||||
|
$wheres[] = 'a.enfermera_id = ?';
|
||||||
|
$params[] = $enfermeraId;
|
||||||
|
}
|
||||||
|
|
||||||
|
$where = $wheres ? 'WHERE ' . implode(' AND ', $wheres) : '';
|
||||||
|
|
||||||
|
$filas = $db->fetchAll(
|
||||||
|
"SELECT
|
||||||
|
d.id,
|
||||||
|
d.fecha_programada,
|
||||||
|
d.pago_fecha,
|
||||||
|
p.nombre_completo AS paciente,
|
||||||
|
p.numero_documento,
|
||||||
|
COALESCE(e.nombre_completo,'Sin asignar') AS enfermera,
|
||||||
|
d.tipo_cliente,
|
||||||
|
COALESCE(d.seguro_nombre,'') AS seguro_nombre,
|
||||||
|
d.estado AS dom_estado,
|
||||||
|
COALESCE(d.valor_domicilio, 0) AS valor_domicilio,
|
||||||
|
d.pago_estado,
|
||||||
|
COALESCE(d.pago_modo,'') AS pago_modo,
|
||||||
|
COALESCE(d.pago_monto, 0) AS pago_monto,
|
||||||
|
COALESCE(d.pago_notas,'') AS pago_notas
|
||||||
|
FROM lab_domicilios d
|
||||||
|
JOIN lab_pacientes p ON p.id = d.paciente_id
|
||||||
|
LEFT JOIN lab_asignaciones a ON a.domicilio_id = d.id AND a.estado NOT IN ('liberada')
|
||||||
|
LEFT JOIN lab_enfermeras e ON e.id = a.enfermera_id
|
||||||
|
$where
|
||||||
|
ORDER BY d.fecha_programada ASC, d.id ASC",
|
||||||
|
$params
|
||||||
|
);
|
||||||
|
|
||||||
|
// Resumen financiero
|
||||||
|
$resumen = [
|
||||||
|
'total' => count($filas),
|
||||||
|
'pagados' => 0,
|
||||||
|
'pendientes' => 0,
|
||||||
|
'exentos' => 0,
|
||||||
|
'monto_total' => 0.0,
|
||||||
|
'por_modo' => [],
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach ($filas as $f) {
|
||||||
|
$est = $f['pago_estado'] ?? 'pendiente';
|
||||||
|
if ($est === 'pagado') {
|
||||||
|
$resumen['pagados']++;
|
||||||
|
$resumen['monto_total'] += (float)$f['pago_monto'];
|
||||||
|
$key = $f['pago_modo'] ?: 'sin_registrar';
|
||||||
|
$resumen['por_modo'][$key] = ($resumen['por_modo'][$key] ?? 0.0) + (float)$f['pago_monto'];
|
||||||
|
} elseif ($est === 'exento') {
|
||||||
|
$resumen['exentos']++;
|
||||||
|
} else {
|
||||||
|
$resumen['pendientes']++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Lista de enfermeras para poblar el selector
|
||||||
|
$enfermeras = $db->fetchAll(
|
||||||
|
"SELECT id, nombre_completo FROM lab_enfermeras WHERE is_active = 1 ORDER BY nombre_completo"
|
||||||
|
);
|
||||||
|
|
||||||
|
echo json_encode([
|
||||||
|
'success' => true,
|
||||||
|
'filas' => $filas,
|
||||||
|
'resumen' => $resumen,
|
||||||
|
'enfermeras' => $enfermeras,
|
||||||
|
], JSON_UNESCAPED_UNICODE);
|
||||||
@@ -136,6 +136,67 @@ if ($tipo) {
|
|||||||
$headers = ['ID','Nombre','Tipo Doc.','Documento','Teléfono','Email','EPS','Ciudad','Barrio','Activo','Total Órdenes','Registrado'];
|
$headers = ['ID','Nombre','Tipo Doc.','Documento','Teléfono','Email','EPS','Ciudad','Barrio','Activo','Total Órdenes','Registrado'];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'pagos':
|
||||||
|
$pModo = in_array($_GET['modo'] ?? '', ['dia','mes','rango']) ? $_GET['modo'] : 'dia';
|
||||||
|
$pWheres = [];
|
||||||
|
$pParams = [];
|
||||||
|
switch ($pModo) {
|
||||||
|
case 'mes':
|
||||||
|
$pAnio = isset($_GET['anio']) && ctype_digit($_GET['anio']) ? (int)$_GET['anio'] : (int)date('Y');
|
||||||
|
$pMes = isset($_GET['mes']) && ctype_digit($_GET['mes']) ? (int)$_GET['mes'] : (int)date('n');
|
||||||
|
if ($pMes < 1 || $pMes > 12) $pMes = (int)date('n');
|
||||||
|
$pWheres[] = 'YEAR(d.fecha_programada) = ?'; $pParams[] = $pAnio;
|
||||||
|
$pWheres[] = 'MONTH(d.fecha_programada) = ?'; $pParams[] = $pMes;
|
||||||
|
$rangoNombre = sprintf('%04d-%02d', $pAnio, $pMes);
|
||||||
|
break;
|
||||||
|
case 'rango':
|
||||||
|
$pDesde = $_GET['desde'] ?? date('Y-m-01');
|
||||||
|
$pHasta = $_GET['hasta'] ?? date('Y-m-d');
|
||||||
|
if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $pDesde)) $pDesde = date('Y-m-01');
|
||||||
|
if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $pHasta)) $pHasta = date('Y-m-d');
|
||||||
|
$pWheres[] = 'DATE(d.fecha_programada) BETWEEN ? AND ?';
|
||||||
|
$pParams[] = $pDesde; $pParams[] = $pHasta;
|
||||||
|
$rangoNombre = "{$pDesde}_{$pHasta}";
|
||||||
|
break;
|
||||||
|
default: // dia
|
||||||
|
$pFecha = $_GET['fecha'] ?? date('Y-m-d');
|
||||||
|
if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $pFecha)) $pFecha = date('Y-m-d');
|
||||||
|
$pWheres[] = 'DATE(d.fecha_programada) = ?';
|
||||||
|
$pParams[] = $pFecha;
|
||||||
|
$rangoNombre = $pFecha;
|
||||||
|
}
|
||||||
|
if (!empty($_GET['enfermera_id']) && ctype_digit($_GET['enfermera_id'])) {
|
||||||
|
$pWheres[] = 'a.enfermera_id = ?';
|
||||||
|
$pParams[] = (int)$_GET['enfermera_id'];
|
||||||
|
}
|
||||||
|
$pWhere = $pWheres ? 'WHERE ' . implode(' AND ', $pWheres) : '';
|
||||||
|
$rows = $db->fetchAll(
|
||||||
|
"SELECT d.id, d.fecha_programada, d.pago_fecha,
|
||||||
|
p.nombre_completo AS paciente, p.numero_documento,
|
||||||
|
COALESCE(e.nombre_completo,'Sin asignar') AS enfermera,
|
||||||
|
d.tipo_cliente, COALESCE(d.seguro_nombre,'') AS seguro,
|
||||||
|
d.estado AS dom_estado,
|
||||||
|
COALESCE(d.valor_domicilio,0) AS valor_domicilio,
|
||||||
|
COALESCE(d.pago_estado,'pendiente') AS pago_estado,
|
||||||
|
COALESCE(d.pago_modo,'') AS pago_modo,
|
||||||
|
COALESCE(d.pago_monto,0) AS pago_monto,
|
||||||
|
COALESCE(d.pago_notas,'') AS pago_notas
|
||||||
|
FROM lab_domicilios d
|
||||||
|
JOIN lab_pacientes p ON p.id = d.paciente_id
|
||||||
|
LEFT JOIN lab_asignaciones a ON a.domicilio_id = d.id AND a.estado NOT IN ('liberada')
|
||||||
|
LEFT JOIN lab_enfermeras e ON e.id = a.enfermera_id
|
||||||
|
$pWhere
|
||||||
|
ORDER BY d.fecha_programada ASC, d.id ASC",
|
||||||
|
$pParams
|
||||||
|
);
|
||||||
|
$filename = "reporte_pagos_{$rangoNombre}.csv";
|
||||||
|
$headers = [
|
||||||
|
'ID','Fecha programada','Fecha pago','Paciente','Documento',
|
||||||
|
'Enfermero/a','Tipo cliente','Seguro','Estado domicilio',
|
||||||
|
'Valor domicilio','Estado pago','Modo pago','Monto recibido','Notas pago',
|
||||||
|
];
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
http_response_code(400);
|
http_response_code(400);
|
||||||
exit('Tipo de exportación no válido');
|
exit('Tipo de exportación no válido');
|
||||||
@@ -244,6 +305,100 @@ $adminNombre = $_SESSION['admin_user']['full_name'] ?? $_SESSION['admin_user']['
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- ══════════════════════════════════════════════════════════════ -->
|
||||||
|
<!-- Reporte de Pagos recibidos -->
|
||||||
|
<!-- ══════════════════════════════════════════════════════════════ -->
|
||||||
|
<div class="card border-0 shadow-sm mb-4">
|
||||||
|
<div class="card-header bg-white border-0 pb-0">
|
||||||
|
<h6 class="fw-semibold mb-2">
|
||||||
|
<i class="fas fa-money-bill-wave me-2 text-success"></i>Informe de pagos recibidos en domicilios
|
||||||
|
</h6>
|
||||||
|
<div class="d-flex flex-wrap gap-2 align-items-end pb-2">
|
||||||
|
<div>
|
||||||
|
<label class="form-label small text-muted text-uppercase mb-1">Período</label>
|
||||||
|
<select id="pago-modo" class="form-select form-select-sm" onchange="pagoToggleModo()" style="min-width:110px">
|
||||||
|
<option value="dia">Por día</option>
|
||||||
|
<option value="mes">Por mes</option>
|
||||||
|
<option value="rango">Rango fechas</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<!-- Día -->
|
||||||
|
<div id="pago-wrap-dia">
|
||||||
|
<label class="form-label small text-muted text-uppercase mb-1">Fecha</label>
|
||||||
|
<input type="date" id="pago-fecha" class="form-control form-control-sm" value="<?= date('Y-m-d') ?>">
|
||||||
|
</div>
|
||||||
|
<!-- Mes -->
|
||||||
|
<div id="pago-wrap-anio" style="display:none">
|
||||||
|
<label class="form-label small text-muted text-uppercase mb-1">Año</label>
|
||||||
|
<input type="number" id="pago-anio" class="form-control form-control-sm" value="<?= date('Y') ?>" min="2020" max="2099" style="width:88px">
|
||||||
|
</div>
|
||||||
|
<div id="pago-wrap-mes" style="display:none">
|
||||||
|
<label class="form-label small text-muted text-uppercase mb-1">Mes</label>
|
||||||
|
<select id="pago-mes" class="form-select form-select-sm" style="width:120px">
|
||||||
|
<option value="1">Enero</option><option value="2">Febrero</option>
|
||||||
|
<option value="3">Marzo</option><option value="4">Abril</option>
|
||||||
|
<option value="5">Mayo</option><option value="6">Junio</option>
|
||||||
|
<option value="7">Julio</option><option value="8">Agosto</option>
|
||||||
|
<option value="9">Septiembre</option><option value="10">Octubre</option>
|
||||||
|
<option value="11">Noviembre</option><option value="12">Diciembre</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<!-- Rango -->
|
||||||
|
<div id="pago-wrap-desde" style="display:none">
|
||||||
|
<label class="form-label small text-muted text-uppercase mb-1">Desde</label>
|
||||||
|
<input type="date" id="pago-desde" class="form-control form-control-sm" value="<?= date('Y-m-01') ?>">
|
||||||
|
</div>
|
||||||
|
<div id="pago-wrap-hasta" style="display:none">
|
||||||
|
<label class="form-label small text-muted text-uppercase mb-1">Hasta</label>
|
||||||
|
<input type="date" id="pago-hasta" class="form-control form-control-sm" value="<?= date('Y-m-d') ?>">
|
||||||
|
</div>
|
||||||
|
<!-- Enfermero -->
|
||||||
|
<div>
|
||||||
|
<label class="form-label small text-muted text-uppercase mb-1">Enfermero/a</label>
|
||||||
|
<select id="pago-enfermera" class="form-select form-select-sm" style="min-width:160px">
|
||||||
|
<option value="">Todos</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<button class="btn btn-primary btn-sm" onclick="cargarReportePagos()">
|
||||||
|
<i class="fas fa-sync-alt me-1"></i>Ver informe
|
||||||
|
</button>
|
||||||
|
<button class="btn btn-sm btn-outline-success" onclick="exportarReportePagos()">
|
||||||
|
<i class="fas fa-file-excel me-1"></i>Excel
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- Resumen KPIs -->
|
||||||
|
<div id="pago-resumen" class="px-3 py-2 border-bottom bg-light" style="display:none">
|
||||||
|
<div class="row g-2 text-center">
|
||||||
|
<div class="col-6 col-md-3">
|
||||||
|
<div class="fw-bold fs-5 text-secondary" id="pr-total">—</div>
|
||||||
|
<div class="small text-muted">Total domicilios</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-6 col-md-3">
|
||||||
|
<div class="fw-bold fs-5 text-success" id="pr-pagados">—</div>
|
||||||
|
<div class="small text-muted">Pagados</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-6 col-md-3">
|
||||||
|
<div class="fw-bold fs-5 text-warning" id="pr-pendientes">—</div>
|
||||||
|
<div class="small text-muted">Pendientes</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-6 col-md-3">
|
||||||
|
<div class="fw-bold fs-5" style="color:#7b1fa2" id="pr-monto">—</div>
|
||||||
|
<div class="small text-muted">Total recibido</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="pr-modos" class="d-flex flex-wrap gap-3 justify-content-center mt-2" style="font-size:.82rem"></div>
|
||||||
|
</div>
|
||||||
|
<!-- Tabla -->
|
||||||
|
<div class="card-body p-0">
|
||||||
|
<div id="pago-tabla-wrap" style="overflow-x:auto">
|
||||||
|
<div class="text-center py-4 text-muted small">
|
||||||
|
<i class="fas fa-info-circle me-1"></i>Selecciona los filtros y haz clic en <strong>Ver informe</strong>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- ══════════════════════════════════════════════════════════════ -->
|
<!-- ══════════════════════════════════════════════════════════════ -->
|
||||||
<!-- Reporte domicilios por enfermero -->
|
<!-- Reporte domicilios por enfermero -->
|
||||||
<!-- ══════════════════════════════════════════════════════════════ -->
|
<!-- ══════════════════════════════════════════════════════════════ -->
|
||||||
@@ -563,6 +718,161 @@ function exportarReporteEnfermero() {
|
|||||||
window.open(`lab_reportes.php?${params}`, '_blank');
|
window.open(`lab_reportes.php?${params}`, '_blank');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ── Reporte de Pagos ───────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
function pagoToggleModo() {
|
||||||
|
const modo = document.getElementById('pago-modo').value;
|
||||||
|
document.getElementById('pago-wrap-dia').style.display = modo === 'dia' ? '' : 'none';
|
||||||
|
document.getElementById('pago-wrap-anio').style.display = modo === 'mes' ? '' : 'none';
|
||||||
|
document.getElementById('pago-wrap-mes').style.display = modo === 'mes' ? '' : 'none';
|
||||||
|
document.getElementById('pago-wrap-desde').style.display = modo === 'rango' ? '' : 'none';
|
||||||
|
document.getElementById('pago-wrap-hasta').style.display = modo === 'rango' ? '' : 'none';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Seleccionar el mes actual al cargar
|
||||||
|
(function initPagoMes() {
|
||||||
|
const mes = new Date().getMonth() + 1;
|
||||||
|
const sel = document.getElementById('pago-mes');
|
||||||
|
if (sel) sel.value = mes;
|
||||||
|
})();
|
||||||
|
|
||||||
|
async function cargarReportePagos() {
|
||||||
|
const wrap = document.getElementById('pago-tabla-wrap');
|
||||||
|
wrap.innerHTML = '<div class="text-center py-4 text-muted"><i class="fas fa-spinner fa-spin"></i> Cargando…</div>';
|
||||||
|
document.getElementById('pago-resumen').style.display = 'none';
|
||||||
|
|
||||||
|
const params = _pagoParams();
|
||||||
|
|
||||||
|
try {
|
||||||
|
const r = await fetch(`api/lab/get_reporte_pagos.php?${params}`);
|
||||||
|
const d = await r.json();
|
||||||
|
if (!d.success) throw new Error(d.error || 'Error al cargar');
|
||||||
|
|
||||||
|
// Poblar selector de enfermeras (solo la primera vez)
|
||||||
|
const sel = document.getElementById('pago-enfermera');
|
||||||
|
if (sel.options.length === 1 && d.enfermeras?.length) {
|
||||||
|
d.enfermeras.forEach(e => {
|
||||||
|
const o = document.createElement('option');
|
||||||
|
o.value = e.id;
|
||||||
|
o.textContent = e.nombre_completo;
|
||||||
|
sel.appendChild(o);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Resumen KPIs
|
||||||
|
const rs = d.resumen || {};
|
||||||
|
document.getElementById('pr-total').textContent = rs.total ?? 0;
|
||||||
|
document.getElementById('pr-pagados').textContent = rs.pagados ?? 0;
|
||||||
|
document.getElementById('pr-pendientes').textContent = rs.pendientes ?? 0;
|
||||||
|
document.getElementById('pr-monto').textContent = fmtMoney(rs.monto_total);
|
||||||
|
|
||||||
|
const modosEl = document.getElementById('pr-modos');
|
||||||
|
const MODO_LABEL = { efectivo:'Efectivo', transferencia:'Transferencia', otro:'Otro', sin_registrar:'Sin modo' };
|
||||||
|
const modos = Object.entries(rs.por_modo || {});
|
||||||
|
modosEl.innerHTML = modos.length
|
||||||
|
? modos.map(([k, v]) =>
|
||||||
|
`<span class="badge bg-secondary">${esc(MODO_LABEL[k] || k)}: ${fmtMoney(v)}</span>`
|
||||||
|
).join('')
|
||||||
|
: '';
|
||||||
|
document.getElementById('pago-resumen').style.display = '';
|
||||||
|
|
||||||
|
// Tabla de detalle
|
||||||
|
if (!d.filas?.length) {
|
||||||
|
wrap.innerHTML = '<p class="text-muted text-center py-3 small">Sin domicilios para los filtros seleccionados.</p>';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const PAGO_BADGE = { pagado:'success', pendiente:'warning', exento:'secondary' };
|
||||||
|
const DOM_BADGE = { completado:'success', cancelado:'danger', programado:'secondary',
|
||||||
|
confirmado:'info', en_camino:'primary', reprogramado:'dark' };
|
||||||
|
|
||||||
|
wrap.innerHTML = `
|
||||||
|
<table class="table table-sm table-hover mb-0" style="font-size:.83rem">
|
||||||
|
<thead class="table-light sticky-top">
|
||||||
|
<tr>
|
||||||
|
<th class="ps-3">#</th>
|
||||||
|
<th>Fecha prog.</th>
|
||||||
|
<th>Paciente</th>
|
||||||
|
<th>Documento</th>
|
||||||
|
<th>Enfermero/a</th>
|
||||||
|
<th>Tipo cliente</th>
|
||||||
|
<th class="text-end">Valor domicilio</th>
|
||||||
|
<th class="text-center">Estado pago</th>
|
||||||
|
<th class="text-center">Modo pago</th>
|
||||||
|
<th class="text-end">Monto recibido</th>
|
||||||
|
<th>Fecha pago</th>
|
||||||
|
<th>Estado domicilio</th>
|
||||||
|
<th>Notas pago</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
${d.filas.map(f => {
|
||||||
|
const pagoEst = f.pago_estado || 'pendiente';
|
||||||
|
const domEst = f.dom_estado || '';
|
||||||
|
const cliente = f.tipo_cliente === 'seguro' && f.seguro_nombre
|
||||||
|
? `Seguro: ${esc(f.seguro_nombre)}`
|
||||||
|
: esc(f.tipo_cliente || 'particular');
|
||||||
|
return `<tr class="${pagoEst === 'pagado' ? '' : 'opacity-75'}">
|
||||||
|
<td class="ps-3 text-muted">${f.id}</td>
|
||||||
|
<td class="text-nowrap">${esc(f.fecha_programada?.slice(0,10) || '—')}</td>
|
||||||
|
<td class="fw-semibold text-nowrap">${esc(f.paciente)}</td>
|
||||||
|
<td class="text-muted">${esc(f.numero_documento || '—')}</td>
|
||||||
|
<td class="text-nowrap">${esc(f.enfermera)}</td>
|
||||||
|
<td class="small">${cliente}</td>
|
||||||
|
<td class="text-end">${fmtMoney(f.valor_domicilio)}</td>
|
||||||
|
<td class="text-center">
|
||||||
|
<span class="badge bg-${PAGO_BADGE[pagoEst] || 'secondary'}">${esc(pagoEst)}</span>
|
||||||
|
</td>
|
||||||
|
<td class="text-center text-muted small">${esc(f.pago_modo) || '—'}</td>
|
||||||
|
<td class="text-end fw-semibold ${pagoEst === 'pagado' ? 'text-success' : 'text-muted'}">
|
||||||
|
${pagoEst === 'pagado' ? fmtMoney(f.pago_monto) : '—'}
|
||||||
|
</td>
|
||||||
|
<td class="text-nowrap text-muted small">${f.pago_fecha ? esc(f.pago_fecha.slice(0,16)) : '—'}</td>
|
||||||
|
<td>
|
||||||
|
<span class="badge bg-${DOM_BADGE[domEst] || 'secondary'}">${esc(domEst)}</span>
|
||||||
|
</td>
|
||||||
|
<td class="text-muted small" style="max-width:160px;white-space:normal">${esc(f.pago_notas) || ''}</td>
|
||||||
|
</tr>`;
|
||||||
|
}).join('')}
|
||||||
|
</tbody>
|
||||||
|
<tfoot class="table-light fw-semibold">
|
||||||
|
<tr>
|
||||||
|
<td colspan="6" class="ps-3">Total</td>
|
||||||
|
<td class="text-end">${fmtMoney(d.filas.reduce((s,f) => s + parseFloat(f.valor_domicilio||0), 0))}</td>
|
||||||
|
<td></td><td></td>
|
||||||
|
<td class="text-end text-success">${fmtMoney(rs.monto_total)}</td>
|
||||||
|
<td colspan="3"></td>
|
||||||
|
</tr>
|
||||||
|
</tfoot>
|
||||||
|
</table>`;
|
||||||
|
} catch (e) {
|
||||||
|
wrap.innerHTML = `<div class="alert alert-danger m-3 small">${esc(e.message)}</div>`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function exportarReportePagos() {
|
||||||
|
const p = _pagoParams();
|
||||||
|
p.set('export', 'pagos');
|
||||||
|
window.open(`lab_reportes.php?${p}`, '_blank');
|
||||||
|
}
|
||||||
|
|
||||||
|
function _pagoParams() {
|
||||||
|
const modo = document.getElementById('pago-modo').value;
|
||||||
|
const enf = document.getElementById('pago-enfermera').value;
|
||||||
|
const p = new URLSearchParams({ modo });
|
||||||
|
if (modo === 'dia') {
|
||||||
|
p.set('fecha', document.getElementById('pago-fecha').value || '<?= date('Y-m-d') ?>');
|
||||||
|
} else if (modo === 'mes') {
|
||||||
|
p.set('anio', document.getElementById('pago-anio').value || '<?= date('Y') ?>');
|
||||||
|
p.set('mes', document.getElementById('pago-mes').value || '<?= date('n') ?>');
|
||||||
|
} else {
|
||||||
|
p.set('desde', document.getElementById('pago-desde').value || '<?= date('Y-m-01') ?>');
|
||||||
|
p.set('hasta', document.getElementById('pago-hasta').value || '<?= date('Y-m-d') ?>');
|
||||||
|
}
|
||||||
|
if (enf) p.set('enfermera_id', enf);
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
// ── Carga todo en paralelo ──────────────────────────────────────────────────
|
// ── Carga todo en paralelo ──────────────────────────────────────────────────
|
||||||
async function cargarTodo() {
|
async function cargarTodo() {
|
||||||
const desde = fecha('rpt-desde');
|
const desde = fecha('rpt-desde');
|
||||||
@@ -572,6 +882,7 @@ async function cargarTodo() {
|
|||||||
cargarResumenOrdenes(desde, hasta),
|
cargarResumenOrdenes(desde, hasta),
|
||||||
cargarActividad(1),
|
cargarActividad(1),
|
||||||
cargarReporteEnfermero(),
|
cargarReporteEnfermero(),
|
||||||
|
cargarReportePagos(),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user