up
This commit is contained in:
@@ -90,7 +90,24 @@ $filas = $db->fetchAll(
|
||||
$params
|
||||
);
|
||||
|
||||
// Resumen financiero
|
||||
// Enriquecer con parcialidades de pago
|
||||
$domIds = array_column($filas, 'id');
|
||||
$parciales = [];
|
||||
if ($domIds) {
|
||||
$in = implode(',', array_map('intval', $domIds));
|
||||
$rows = $db->fetchAll(
|
||||
"SELECT domicilio_id, modo, monto, notas FROM lab_domicilio_pagos WHERE domicilio_id IN ($in) ORDER BY id ASC"
|
||||
);
|
||||
foreach ($rows as $row) {
|
||||
$parciales[(int)$row['domicilio_id']][] = $row;
|
||||
}
|
||||
}
|
||||
foreach ($filas as &$f) {
|
||||
$f['pagos_detalle'] = $parciales[(int)$f['id']] ?? [];
|
||||
}
|
||||
unset($f);
|
||||
|
||||
// Resumen financiero — sumar desde parcialidades cuando existen
|
||||
$resumen = [
|
||||
'total' => count($filas),
|
||||
'pagados' => 0,
|
||||
@@ -104,9 +121,21 @@ 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'];
|
||||
if (!empty($f['pagos_detalle'])) {
|
||||
// Sumar desde parcialidades
|
||||
foreach ($f['pagos_detalle'] as $p) {
|
||||
$monto = (float)$p['monto'];
|
||||
$key = $p['modo'] ?: 'sin_registrar';
|
||||
$resumen['monto_total'] += $monto;
|
||||
$resumen['por_modo'][$key] = ($resumen['por_modo'][$key] ?? 0.0) + $monto;
|
||||
}
|
||||
} else {
|
||||
// Fallback registro legacy
|
||||
$monto = (float)$f['pago_monto'];
|
||||
$key = $f['pago_modo'] ?: 'sin_registrar';
|
||||
$resumen['monto_total'] += $monto;
|
||||
$resumen['por_modo'][$key] = ($resumen['por_modo'][$key] ?? 0.0) + $monto;
|
||||
}
|
||||
} elseif ($est === 'exento') {
|
||||
$resumen['exentos']++;
|
||||
} else {
|
||||
|
||||
@@ -32,12 +32,18 @@ try {
|
||||
// Agenda del día con pleno detalle
|
||||
$agenda = $enf->agenda($eid, $fecha);
|
||||
|
||||
// Enriquecer con servicios extra (el resto ya viene de la query agenda())
|
||||
// Enriquecer con servicios extra y pagos parciales
|
||||
$db = Database::getInstance();
|
||||
foreach ($agenda as &$item) {
|
||||
$domId = (int)$item['domicilio_id'];
|
||||
$item['servicios_extra'] = $db->fetchAll(
|
||||
"SELECT * FROM lab_servicios_extra WHERE domicilio_id = ? ORDER BY created_at ASC",
|
||||
[(int)$item['domicilio_id']]
|
||||
[$domId]
|
||||
);
|
||||
// Parcialidades de pago (tabla nueva); vacío si no hay pagos registrados
|
||||
$item['pagos_detalle'] = $db->fetchAll(
|
||||
"SELECT modo, monto, notas FROM lab_domicilio_pagos WHERE domicilio_id = ? ORDER BY id ASC",
|
||||
[$domId]
|
||||
);
|
||||
}
|
||||
unset($item);
|
||||
|
||||
+53
-18
@@ -2,15 +2,17 @@
|
||||
/**
|
||||
* POST /api/lab/registrar_pago.php
|
||||
* Registra el pago de un domicilio por parte del cliente.
|
||||
* Solo puede llamarse desde el portal del enfermero o por un admin.
|
||||
* Soporta múltiples métodos de pago (pagos parciales).
|
||||
*
|
||||
* Body JSON:
|
||||
* {
|
||||
* domicilio_id: int,
|
||||
* pago_estado: 'pagado' | 'exento' | 'pendiente',
|
||||
* pago_modo: 'efectivo' | 'transferencia' | 'otro', (requerido si pagado)
|
||||
* pago_monto: float, (requerido si pagado)
|
||||
* pago_notas: string|null
|
||||
* pagos: [ (requerido si pagado)
|
||||
* { modo: 'efectivo'|'transferencia'|'otro', monto: float, notas: string|null },
|
||||
* ...
|
||||
* ],
|
||||
* pago_notas: string|null (nota general, opcional)
|
||||
* }
|
||||
*/
|
||||
require_once __DIR__ . '/_helpers.php';
|
||||
@@ -22,33 +24,64 @@ try {
|
||||
$domId = (int)($datos['domicilio_id'] ?? 0);
|
||||
$estado = $datos['pago_estado'] ?? '';
|
||||
|
||||
if (!$domId) jsonError('domicilio_id requerido');
|
||||
if (!$domId) jsonError('domicilio_id requerido');
|
||||
if (!in_array($estado, ['pagado', 'exento', 'pendiente'], true))
|
||||
jsonError('pago_estado inválido (pagado|exento|pendiente)');
|
||||
|
||||
$pagos = [];
|
||||
if ($estado === 'pagado') {
|
||||
if (empty($datos['pago_modo']) || !in_array($datos['pago_modo'], ['efectivo','transferencia','otro'], true))
|
||||
jsonError('pago_modo inválido (efectivo|transferencia|otro)');
|
||||
if (!isset($datos['pago_monto']) || (float)$datos['pago_monto'] <= 0)
|
||||
jsonError('pago_monto debe ser mayor a 0');
|
||||
$raw = $datos['pagos'] ?? [];
|
||||
if (!is_array($raw) || empty($raw)) jsonError('Se requiere al menos un método de pago');
|
||||
$modosValidos = ['efectivo', 'transferencia', 'otro'];
|
||||
foreach ($raw as $i => $p) {
|
||||
$modo = $p['modo'] ?? '';
|
||||
$monto = (float)($p['monto'] ?? 0);
|
||||
if (!in_array($modo, $modosValidos, true)) jsonError("Método de pago inválido en fila " . ($i + 1));
|
||||
if ($monto <= 0) jsonError("El monto debe ser mayor a 0 en fila " . ($i + 1));
|
||||
$pagos[] = [
|
||||
'modo' => $modo,
|
||||
'monto' => $monto,
|
||||
'notas' => isset($p['notas']) && $p['notas'] !== '' ? trim($p['notas']) : null,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
$adminId = adminId();
|
||||
$dom = new Domicilio();
|
||||
$db = Database::getInstance();
|
||||
|
||||
// Verificar que existe
|
||||
$exist = Database::getInstance()->fetch(
|
||||
'SELECT id, pago_estado FROM lab_domicilios WHERE id = ?', [$domId]
|
||||
);
|
||||
$exist = $db->fetch('SELECT id, pago_estado FROM lab_domicilios WHERE id = ?', [$domId]);
|
||||
if (!$exist) jsonError("Domicilio #$domId no encontrado");
|
||||
|
||||
// ── Persistir parcialidades ──────────────────────────────────────────
|
||||
// Eliminar registros previos y reinsertar (permite editar el pago)
|
||||
$db->execute('DELETE FROM lab_domicilio_pagos WHERE domicilio_id = ?', [$domId]);
|
||||
|
||||
$totalMonto = 0;
|
||||
$primerModo = null;
|
||||
$notasGeneral = !empty($datos['pago_notas']) ? trim($datos['pago_notas']) : null;
|
||||
|
||||
if ($estado === 'pagado') {
|
||||
foreach ($pagos as $p) {
|
||||
$db->execute(
|
||||
'INSERT INTO lab_domicilio_pagos (domicilio_id, modo, monto, notas) VALUES (?, ?, ?, ?)',
|
||||
[$domId, $p['modo'], $p['monto'], $p['notas']]
|
||||
);
|
||||
$totalMonto += $p['monto'];
|
||||
if ($primerModo === null) $primerModo = $p['modo'];
|
||||
}
|
||||
}
|
||||
|
||||
// ── Actualizar campos resumen en lab_domicilios ─────────────────────
|
||||
// pago_modo guarda el primer método (o el único); pago_monto guarda el total.
|
||||
$campos = [
|
||||
'pago_estado' => $estado,
|
||||
'pago_modo' => ($estado === 'pagado') ? ($datos['pago_modo'] ?? null) : null,
|
||||
'pago_monto' => ($estado === 'pagado') ? ((float)$datos['pago_monto']) : null,
|
||||
'pago_fecha' => ($estado === 'pagado') ? date('Y-m-d H:i:s') : null,
|
||||
'pago_notas' => !empty($datos['pago_notas']) ? trim($datos['pago_notas']) : null,
|
||||
'pago_registrado_por' => $adminId,
|
||||
'pago_estado' => $estado,
|
||||
'pago_modo' => ($estado === 'pagado') ? $primerModo : null,
|
||||
'pago_monto' => ($estado === 'pagado') ? $totalMonto : null,
|
||||
'pago_fecha' => ($estado === 'pagado') ? date('Y-m-d H:i:s') : null,
|
||||
'pago_notas' => $notasGeneral,
|
||||
'pago_registrado_por' => $adminId,
|
||||
];
|
||||
|
||||
$dom->actualizar($domId, $campos, $adminId);
|
||||
@@ -56,6 +89,8 @@ try {
|
||||
jsonOk([
|
||||
'domicilio_id' => $domId,
|
||||
'pago_estado' => $estado,
|
||||
'pago_total' => $totalMonto,
|
||||
'pagos' => $pagos,
|
||||
], 'Pago registrado correctamente');
|
||||
|
||||
} catch (InvalidArgumentException $e) {
|
||||
|
||||
Reference in New Issue
Block a user