mas cambios 2

This commit is contained in:
Jhonathan Guevara 2026-01-06 14:05:05 -05:00
parent b8c258a963
commit 6ace09ec6c
Signed by: jhonathan_guevara
GPG Key ID: 619239F12DCBE55B
9 changed files with 491 additions and 48 deletions

View File

@ -2539,7 +2539,11 @@ async function crearLibroAutorizacion(a) {
sheet.mergeCells('O35:R35'); sheet.mergeCells('O35:R35');
sheet.mergeCells('B24:R24'); sheet.mergeCells('B24:R24');
sheet.mergeCells('B25:G30'); sheet.mergeCells('B25:G30');
sheet.mergeCells('H25:R29'); sheet.mergeCells('H25:R25');
sheet.mergeCells('H26:R26');
sheet.mergeCells('H27:R27');
sheet.mergeCells('H28:R28');
sheet.mergeCells('H29:R29');
sheet.mergeCells('H30:R30'); sheet.mergeCells('H30:R30');
sheet.mergeCells('B31:G32'); sheet.mergeCells('B31:G32');
sheet.mergeCells('H31:R31'); sheet.mergeCells('H31:R31');
@ -2658,6 +2662,32 @@ async function crearLibroAutorizacion(a) {
.replace(/\s+/g, ' ') .replace(/\s+/g, ' ')
.trim(); .trim();
const emptyIpsValues = new Set([
'NA',
'SD',
'SINDATO',
'SINDATOS',
'SININFO',
'SININFORMACION',
'NOAPLICA',
'NONE',
'NULL',
]);
const cleanIpsValue = (value) => {
const raw = String(value || '').trim();
if (!raw) return '';
const normalized = raw
.normalize('NFD')
.replace(/[\u0300-\u036f]/g, '')
.toUpperCase()
.replace(/[^A-Z0-9]/g, '');
if (!normalized || emptyIpsValues.has(normalized)) {
return '';
}
return raw;
};
// 1) Número de autorización (F8:I8) // 1) Número de autorización (F8:I8)
['F8', 'G8', 'H8', 'I8'].forEach(celda => { ['F8', 'G8', 'H8', 'I8'].forEach(celda => {
sheet.getCell(celda).value = a.numero_autorizacion || ''; sheet.getCell(celda).value = a.numero_autorizacion || '';
@ -2692,12 +2722,12 @@ async function crearLibroAutorizacion(a) {
sheet.getCell(celda).value = nombreIps; sheet.getCell(celda).value = nombreIps;
}); });
const nitIps = a.nit || ''; const nitIps = cleanIpsValue(a.nit);
['D13', 'E13', 'F13', 'G13'].forEach(celda => { ['D13', 'E13', 'F13', 'G13'].forEach(celda => {
sheet.getCell(celda).value = nitIps; sheet.getCell(celda).value = nitIps;
}); });
const telefonoIps = a.telefono_ips || ''; const telefonoIps = cleanIpsValue(a.telefono_ips);
['D14', 'E14', 'F14', 'G14', 'D15', 'E15', 'F15', 'G15', 'D16', 'E16', 'F16', 'G16'].forEach(celda => { ['D14', 'E14', 'F14', 'G14', 'D15', 'E15', 'F15', 'G15', 'D16', 'E16', 'F16', 'G16'].forEach(celda => {
sheet.getCell(celda).value = telefonoIps; sheet.getCell(celda).value = telefonoIps;
}); });
@ -2710,8 +2740,9 @@ async function crearLibroAutorizacion(a) {
}); });
// 5) Dirección IPS (M16:N16) // 5) Dirección IPS (M16:N16)
const direccionIps = cleanIpsValue(a.direccion);
['M13', 'N13','O13', 'P13','Q13', 'R13'].forEach(celda => { ['M13', 'N13','O13', 'P13','Q13', 'R13'].forEach(celda => {
sheet.getCell(celda).value = a.direccion || ''; sheet.getCell(celda).value = direccionIps;
}); });
['M23', 'N23','O23', 'P23','Q23', 'R23'].forEach(celda => { ['M23', 'N23','O23', 'P23','Q23', 'R23'].forEach(celda => {
@ -2719,12 +2750,12 @@ async function crearLibroAutorizacion(a) {
}); });
['M16', 'N16'].forEach(celda => { ['M16', 'N16'].forEach(celda => {
sheet.getCell(celda).value = a.municipio || ''; sheet.getCell(celda).value = cleanIpsValue(a.municipio);
}); });
// 6) Departamento IPS (Q16:R16) // 6) Departamento IPS (Q16:R16)
['Q16', 'R16'].forEach(celda => { ['Q16', 'R16'].forEach(celda => {
sheet.getCell(celda).value = a.departamento || ''; sheet.getCell(celda).value = cleanIpsValue(a.departamento);
}); });
// 7) Nombre completo paciente (H18:R18) // 7) Nombre completo paciente (H18:R18)
@ -2742,10 +2773,36 @@ async function crearLibroAutorizacion(a) {
sheet.getCell(celda).value = a.numero_documento || ''; sheet.getCell(celda).value = a.numero_documento || '';
}); });
['H27','R27'].forEach(celda => { ['H29','R29'].forEach(celda => {
sheet.getCell(celda).value = a.nombre_establecimiento || ''; sheet.getCell(celda).value = a.nombre_establecimiento || '';
}); });
// Tipo de servicio (consulta externa)
const servicioCols = ['H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R'];
const addBottomBorder = (row, style = 'thin') => {
servicioCols.forEach((col) => {
const cell = sheet.getCell(`${col}${row}`);
const border = cell.border || {};
cell.border = {
...border,
bottom: { style, color: { argb: 'FF000000' } },
};
});
};
sheet.getCell('B25').value = 'TIPO DE SERVICIO';
sheet.getCell('B25').alignment = {"horizontal":"center","vertical":"middle"};
sheet.getCell('H25').value = 'CONSULTA EXTERNA';
sheet.getCell('H25').alignment = {"horizontal":"center","vertical":"middle"};
sheet.getCell('H26').value = 'X';
sheet.getCell('H26').alignment = {"horizontal":"center","vertical":"middle"};
sheet.getCell('H27').value = '';
sheet.getCell('H27').alignment = {"horizontal":"center","vertical":"middle"};
sheet.getCell('H28').value = '';
sheet.getCell('H28').alignment = {"horizontal":"center","vertical":"middle"};
addBottomBorder(25);
addBottomBorder(26);
// 10) Observacion / servicios autorizados (H25:R25) // 10) Observacion / servicios autorizados (H25:R25)
const cupCodigo = a.cup_codigo || ''; const cupCodigo = a.cup_codigo || '';
const cupDescripcion = a.cup_descripcion || ''; const cupDescripcion = a.cup_descripcion || '';
@ -2773,11 +2830,32 @@ async function crearLibroAutorizacion(a) {
}); });
return partes.join(' | '); return partes.join(' | ');
}; };
const observacionBase = limpiarObservacion(a.observacion || ''); const filtrarObservacionConsulta = (value) => {
const partes = String(value || '')
.split('|')
.map((parte) => parte.trim())
.filter(Boolean)
.filter((parte) => {
const lower = parte.toLowerCase();
return (
!lower.includes('solicitante') &&
!lower.includes('traslado a departamento')
);
});
return partes.join(' | ');
};
const esConsultaExterna =
String(a.tipo_autorizacion || '').toLowerCase() === 'consultas_externas';
let observacionBase = limpiarObservacion(a.observacion || '');
if (esConsultaExterna) {
observacionBase = filtrarObservacionConsulta(observacionBase);
}
const solicitanteNombre = String(a.nombre_solicitante || '').trim(); const solicitanteNombre = String(a.nombre_solicitante || '').trim();
const observacionLower = observacionBase.toLowerCase(); const observacionLower = observacionBase.toLowerCase();
const solicitanteInfo = const solicitanteInfo =
solicitanteNombre && !observacionLower.includes('solicitante') esConsultaExterna
? ''
: solicitanteNombre && !observacionLower.includes('solicitante')
? `Solicitante: ${solicitanteNombre}` ? `Solicitante: ${solicitanteNombre}`
: ''; : '';
const observacion = [cupInfo, observacionBase, solicitanteInfo] const observacion = [cupInfo, observacionBase, solicitanteInfo]

View File

@ -2338,6 +2338,32 @@ async function crearLibroAutorizacionBrigadasAmbulanciasHospitalarios(a) {
.replace(/\s+/g, ' ') .replace(/\s+/g, ' ')
.trim(); .trim();
const emptyIpsValues = new Set([
'NA',
'SD',
'SINDATO',
'SINDATOS',
'SININFO',
'SININFORMACION',
'NOAPLICA',
'NONE',
'NULL',
]);
const cleanIpsValue = (value) => {
const raw = String(value || '').trim();
if (!raw) return '';
const normalized = raw
.normalize('NFD')
.replace(/[\u0300-\u036f]/g, '')
.toUpperCase()
.replace(/[^A-Z0-9]/g, '');
if (!normalized || emptyIpsValues.has(normalized)) {
return '';
}
return raw;
};
['F8', 'G8', 'H8', 'I8'].forEach((celda) => { ['F8', 'G8', 'H8', 'I8'].forEach((celda) => {
sheet.getCell(celda).value = a.numero_autorizacion || ''; sheet.getCell(celda).value = a.numero_autorizacion || '';
}); });
@ -2368,12 +2394,12 @@ async function crearLibroAutorizacionBrigadasAmbulanciasHospitalarios(a) {
sheet.getCell(celda).value = nombreIps; sheet.getCell(celda).value = nombreIps;
}); });
const nitIps = a.nit || ''; const nitIps = cleanIpsValue(a.nit);
['D13', 'E13', 'F13', 'G13'].forEach((celda) => { ['D13', 'E13', 'F13', 'G13'].forEach((celda) => {
sheet.getCell(celda).value = nitIps; sheet.getCell(celda).value = nitIps;
}); });
const telefonoIps = a.telefono_ips || ''; const telefonoIps = cleanIpsValue(a.telefono_ips);
['D14', 'E14', 'F14', 'G14', 'D15', 'E15', 'F15', 'G15', 'D16', 'E16', 'F16', 'G16'].forEach((celda) => { ['D14', 'E14', 'F14', 'G14', 'D15', 'E15', 'F15', 'G15', 'D16', 'E16', 'F16', 'G16'].forEach((celda) => {
sheet.getCell(celda).value = telefonoIps; sheet.getCell(celda).value = telefonoIps;
}); });
@ -2385,8 +2411,9 @@ async function crearLibroAutorizacionBrigadasAmbulanciasHospitalarios(a) {
sheet.getCell(celda).value = a.sexo || ''; sheet.getCell(celda).value = a.sexo || '';
}); });
const direccionIps = cleanIpsValue(a.direccion);
['M13', 'N13', 'O13', 'P13', 'Q13', 'R13'].forEach((celda) => { ['M13', 'N13', 'O13', 'P13', 'Q13', 'R13'].forEach((celda) => {
sheet.getCell(celda).value = a.direccion || ''; sheet.getCell(celda).value = direccionIps;
}); });
['M23', 'N23', 'O23', 'P23', 'Q23', 'R23'].forEach((celda) => { ['M23', 'N23', 'O23', 'P23', 'Q23', 'R23'].forEach((celda) => {
@ -2394,11 +2421,11 @@ async function crearLibroAutorizacionBrigadasAmbulanciasHospitalarios(a) {
}); });
['M16', 'N16'].forEach((celda) => { ['M16', 'N16'].forEach((celda) => {
sheet.getCell(celda).value = a.municipio || ''; sheet.getCell(celda).value = cleanIpsValue(a.municipio);
}); });
['Q16', 'R16'].forEach((celda) => { ['Q16', 'R16'].forEach((celda) => {
sheet.getCell(celda).value = a.departamento || ''; sheet.getCell(celda).value = cleanIpsValue(a.departamento);
}); });
['H18', 'I18', 'J18', 'K18', 'L18', 'M18', 'N18', 'O18', 'P18', 'Q18', 'R18'].forEach((celda) => { ['H18', 'I18', 'J18', 'K18', 'L18', 'M18', 'N18', 'O18', 'P18', 'Q18', 'R18'].forEach((celda) => {

View File

@ -1507,6 +1507,28 @@ const normalizeDigits = (value) => String(value || '').replace(/\D/g, '');
const normalizeNameKey = (value) => const normalizeNameKey = (value) =>
normalizeSearch(value).replace(/[^A-Z0-9]/g, ''); normalizeSearch(value).replace(/[^A-Z0-9]/g, '');
const IPS_EMPTY_MARKERS = new Set([
'NA',
'SD',
'SINDATO',
'SINDATOS',
'SININFO',
'SININFORMACION',
'NOAPLICA',
'NONE',
'NULL',
]);
const cleanIpsField = (value) => {
const raw = String(value || '').trim();
if (!raw) return '';
const normalized = normalizeSearch(raw).replace(/[^A-Z0-9]/g, '');
if (!normalized || IPS_EMPTY_MARKERS.has(normalized)) {
return '';
}
return raw;
};
const extractCupCodigo = (value) => { const extractCupCodigo = (value) => {
const text = String(value || '').trim(); const text = String(value || '').trim();
if (!text) return ''; if (!text) return '';
@ -1667,19 +1689,18 @@ async function procesarExcelIps(inputFilePath) {
for (let i = 2; i <= sheet.rowCount; i++) { for (let i = 2; i <= sheet.rowCount; i++) {
const row = sheet.getRow(i); const row = sheet.getRow(i);
const nit = getValueMulti(row, [ const nit = cleanIpsField(
'NIT', getValueMulti(row, ['NIT', 'NITIPS', 'NITPRESTADOR', 'NITPRESTADORIPS'])
'NITIPS', );
'NITPRESTADOR', const nombre = cleanIpsField(
'NITPRESTADORIPS', getValueMulti(row, [
]);
const nombre = getValueMulti(row, [
'PRESTADOR', 'PRESTADOR',
'PRESTADORDELSERVICIO', 'PRESTADORDELSERVICIO',
'PRESTADORDESERVICIO', 'PRESTADORDESERVICIO',
'NOMBREPRESTADOR', 'NOMBREPRESTADOR',
'NOMBREIPS', 'NOMBREIPS',
]); ])
);
if (!nit && !nombre) { if (!nit && !nombre) {
continue; continue;
@ -1687,15 +1708,13 @@ async function procesarExcelIps(inputFilePath) {
resumen.total += 1; resumen.total += 1;
const direccion = getValue(row, 'DIRECCION'); const direccion = cleanIpsField(getValue(row, 'DIRECCION'));
const departamento = getValue(row, 'DEPARTAMENTO'); const departamento = cleanIpsField(getValue(row, 'DEPARTAMENTO'));
const municipio = getValue(row, 'MUNICIPIO'); const municipio = cleanIpsField(getValue(row, 'MUNICIPIO'));
const telefono = getValue(row, 'TELEFONO'); const telefono = cleanIpsField(getValue(row, 'TELEFONO'));
const codigoIps = getValueMulti(row, [ const codigoIps = cleanIpsField(
'CODIGOIPS', getValueMulti(row, ['CODIGOIPS', 'CODIGOPRESTADOR', 'CODIGOHABILITACION'])
'CODIGOPRESTADOR', );
'CODIGOHABILITACION',
]);
const nitDigits = registerDigits(nitKeys, nit); const nitDigits = registerDigits(nitKeys, nit);
const codigoDigits = registerDigits(codigoKeys, codigoIps); const codigoDigits = registerDigits(codigoKeys, codigoIps);
@ -1777,16 +1796,18 @@ async function procesarExcelIps(inputFilePath) {
await client.query( await client.query(
` `
UPDATE ips UPDATE ips
SET nombre_ips = COALESCE($1, nombre_ips), SET nit = COALESCE($1, nit),
codigo_ips = COALESCE($2, codigo_ips), nombre_ips = COALESCE($2, nombre_ips),
direccion = COALESCE($3, direccion), codigo_ips = COALESCE($3, codigo_ips),
telefono = COALESCE($4, telefono), direccion = COALESCE($4, direccion),
departamento = COALESCE($5, departamento), telefono = COALESCE($5, telefono),
municipio = COALESCE($6, municipio), departamento = COALESCE($6, departamento),
municipio = COALESCE($7, municipio),
tiene_convenio = true tiene_convenio = true
WHERE id_ips = $7 WHERE id_ips = $8
`, `,
[ [
nit || null,
nombre || null, nombre || null,
codigoIps || null, codigoIps || null,
direccion || null, direccion || null,
@ -5082,6 +5103,98 @@ app.patch('/api/autorizaciones/estado-masivo', verificarToken, esAdministrador,
} }
}); });
/**
* PATCH /api/autorizaciones/autorizante-masivo
* Body: { fecha_inicio, fecha_fin, numero_documento_autorizante, establecimiento?, ambito?, ips? }
* Solo administrador
*/
app.patch('/api/autorizaciones/autorizante-masivo', verificarToken, esAdministrador, async (req, res) => {
const fecha_inicio = req.body?.fecha_inicio || req.query?.fecha_inicio;
const fecha_fin = req.body?.fecha_fin || req.query?.fecha_fin;
const numeroDocumento =
req.body?.numero_documento_autorizante || req.query?.numero_documento_autorizante;
const establecimiento = String(
req.body?.establecimiento || req.query?.establecimiento || ''
).trim();
const ambito = String(req.body?.ambito || req.query?.ambito || '')
.trim()
.toLowerCase();
const ips = String(req.body?.ips || req.query?.ips || '').trim();
if (!fecha_inicio || !fecha_fin) {
return res.status(400).json({ error: 'fecha_inicio y fecha_fin son requeridos' });
}
const numeroAutorizante = Number(numeroDocumento);
if (!Number.isFinite(numeroAutorizante)) {
return res.status(400).json({ error: 'numero_documento_autorizante invalido' });
}
const ambitosPermitidos = ['intramural', 'extramural'];
if (ambito && !ambitosPermitidos.includes(ambito)) {
return res.status(400).json({ error: 'ambito invalido' });
}
try {
const autorizanteRes = await pool.query(
'SELECT 1 FROM autorizante WHERE numero_documento = $1 LIMIT 1',
[numeroAutorizante]
);
if (autorizanteRes.rows.length === 0) {
return res.status(404).json({ error: 'Autorizante no encontrado' });
}
const whereParts = ['a.fecha_autorizacion BETWEEN $2::date AND $3::date'];
const params = [numeroAutorizante, fecha_inicio, fecha_fin];
if (establecimiento) {
params.push(`%${establecimiento}%`);
whereParts.push(
`EXISTS (
SELECT 1
FROM ingreso i
JOIN establecimiento e ON i.codigo_establecimiento = e.codigo_establecimiento
WHERE i.interno = a.interno
AND (e.codigo_establecimiento ILIKE $${params.length} OR e.nombre_establecimiento ILIKE $${params.length})
)`
);
}
if (ambito) {
params.push(ambito);
whereParts.push(`a.ambito_atencion = $${params.length}`);
}
if (ips) {
params.push(`%${ips}%`);
whereParts.push(
`EXISTS (
SELECT 1
FROM ips i
WHERE i.id_ips = a.id_ips
AND (i.nombre_ips ILIKE $${params.length} OR i.nit ILIKE $${params.length} OR i.codigo_ips ILIKE $${params.length})
)`
);
}
const sql = `
UPDATE autorizacion a
SET numero_documento_autorizante = $1
WHERE ${whereParts.join('\n AND ')}
RETURNING a.numero_autorizacion;
`;
const result = await pool.query(sql, params);
return res.json({
mensaje: 'Autorizantes actualizados',
actualizados: result.rowCount || 0,
});
} catch (error) {
console.error('Error en autorizante masivo:', error.message);
return res.status(500).json({ error: 'Error actualizando autorizantes' });
}
});
/** /**
* GET /api/autorizaciones-por-fecha/zip * GET /api/autorizaciones-por-fecha/zip
* Query params: fecha_inicio, fecha_fin * Query params: fecha_inicio, fecha_fin

View File

@ -242,6 +242,36 @@
min-width: 180px; min-width: 180px;
} }
.autorizante-masivo {
display: flex;
align-items: center;
gap: 8px;
padding: 6px 10px;
border-radius: 8px;
background: var(--color-surface);
border: 1px solid var(--color-border);
}
.autorizante-masivo label {
font-size: 0.85rem;
color: var(--color-text-muted);
font-weight: 600;
}
.autorizante-masivo select {
min-width: 200px;
padding: 8px 10px;
border-radius: 6px;
border: 1px solid var(--color-input-border);
background: var(--color-input-bg);
font-size: 0.85rem;
color: var(--color-text-main);
}
.autorizante-masivo button {
min-width: 180px;
}
/* Table */ /* Table */
.table-container { .table-container {
overflow-x: auto; overflow-x: auto;
@ -503,6 +533,11 @@
justify-content: space-between; justify-content: space-between;
} }
.autorizante-masivo {
width: 100%;
justify-content: space-between;
}
.autorizaciones-table th, .autorizaciones-table th,
.autorizaciones-table td { .autorizaciones-table td {
padding: 8px 12px; padding: 8px 12px;
@ -527,7 +562,9 @@
.btn-exportar, .btn-exportar,
.btn-descargar-todos, .btn-descargar-todos,
.estado-masivo, .estado-masivo,
.estado-masivo button { .estado-masivo button,
.autorizante-masivo,
.autorizante-masivo button {
justify-content: center; justify-content: center;
} }
@ -537,11 +574,22 @@
align-items: stretch; align-items: stretch;
} }
.autorizante-masivo {
width: 100%;
flex-direction: column;
align-items: stretch;
}
.estado-masivo select, .estado-masivo select,
.estado-masivo button { .estado-masivo button {
width: 100%; width: 100%;
} }
.autorizante-masivo select,
.autorizante-masivo button {
width: 100%;
}
.empty-state { .empty-state {
padding: 40px 16px; padding: 40px 16px;
} }

View File

@ -149,6 +149,32 @@
{{ actualizandoMasivo ? 'Actualizando...' : 'Aplicar a todo el rango' }} {{ actualizandoMasivo ? 'Actualizando...' : 'Aplicar a todo el rango' }}
</button> </button>
</div> </div>
<div class="autorizante-masivo" *ngIf="esAdmin">
<label for="autorizanteMasivo">Autorizante:</label>
<select
id="autorizanteMasivo"
[(ngModel)]="autorizanteMasivo"
[disabled]="actualizandoAutorizanteMasivo || cargandoAutorizantes"
>
<option value="">
{{ cargandoAutorizantes ? 'Cargando...' : 'Selecciona' }}
</option>
<option
*ngFor="let a of autorizantes"
[value]="a.numero_documento"
>
{{ a.nombre }}
</option>
</select>
<button
class="btn btn-secondary"
type="button"
(click)="aplicarAutorizanteMasivo()"
[disabled]="actualizandoAutorizanteMasivo || !autorizanteMasivo || autorizaciones.length === 0"
>
{{ actualizandoAutorizanteMasivo ? 'Aplicando...' : 'Aplicar autorizante' }}
</button>
</div>
<button <button
class="btn btn-secondary btn-exportar" class="btn btn-secondary btn-exportar"
*ngIf="puedeDescargarMasivo" *ngIf="puedeDescargarMasivo"

View File

@ -27,6 +27,7 @@ export class AutorizacionesPorFechaComponent implements OnInit {
actualizandoEstado: Record<string, boolean> = {}; actualizandoEstado: Record<string, boolean> = {};
actualizandoMasivo = false; actualizandoMasivo = false;
estadoMasivo: 'pendiente' | 'autorizado' | 'no_autorizado' = 'autorizado'; estadoMasivo: 'pendiente' | 'autorizado' | 'no_autorizado' = 'autorizado';
actualizandoAutorizanteMasivo = false;
esAdmin = false; esAdmin = false;
puedeGestionarEntrega = false; puedeGestionarEntrega = false;
puedeDescargarMasivo = false; puedeDescargarMasivo = false;
@ -36,6 +37,9 @@ export class AutorizacionesPorFechaComponent implements OnInit {
ipsFiltro = ''; ipsFiltro = '';
autorizacionesFiltradas: any[] = []; autorizacionesFiltradas: any[] = [];
actualizandoEntrega: Record<string, boolean> = {}; actualizandoEntrega: Record<string, boolean> = {};
autorizantes: any[] = [];
autorizanteMasivo = '';
cargandoAutorizantes = false;
// Para saber si ya buscamos algo // Para saber si ya buscamos algo
hayResultados = false; hayResultados = false;
@ -67,6 +71,10 @@ export class AutorizacionesPorFechaComponent implements OnInit {
this.esAdmin || this.authService.isAdministrativoSede(); this.esAdmin || this.authService.isAdministrativoSede();
this.puedeDescargarMasivo = this.authService.puedeDescargarPdfs(); this.puedeDescargarMasivo = this.authService.puedeDescargarPdfs();
if (this.esAdmin) {
this.cargarAutorizantes();
}
// Rango por defecto: últimos 30 días // Rango por defecto: últimos 30 días
const hoy = new Date(); const hoy = new Date();
const hace30Dias = new Date(hoy.getTime() - 30 * 24 * 60 * 60 * 1000); const hace30Dias = new Date(hoy.getTime() - 30 * 24 * 60 * 60 * 1000);
@ -302,6 +310,77 @@ export class AutorizacionesPorFechaComponent implements OnInit {
}); });
} }
aplicarAutorizanteMasivo(): void {
this.limpiarMensajes();
if (!this.esAdmin) {
this.errorMessage = 'No tienes permisos para actualizar autorizantes.';
return;
}
if (!this.fechaInicioApi || !this.fechaFinApi) {
this.errorMessage = 'Primero realiza una busqueda por fechas.';
return;
}
const autorizadoId = Number(this.autorizanteMasivo);
if (!Number.isFinite(autorizadoId)) {
this.errorMessage = 'Selecciona un autorizante valido.';
return;
}
const autorizado = this.autorizantes.find(
(item) => String(item?.numero_documento) === String(this.autorizanteMasivo)
);
const autorizadoNombre = String(autorizado?.nombre || '').trim();
const autorizadoLabel = autorizadoNombre || String(autorizadoId);
const confirmacion = confirm(
`¿Seguro que deseas aplicar "${autorizadoLabel}" a todas las autorizaciones del rango?`
);
if (!confirmacion) {
return;
}
this.actualizandoAutorizanteMasivo = true;
this.pacienteService
.actualizarAutorizanteMasivo(
this.fechaInicioApi,
this.fechaFinApi,
autorizadoId,
this.establecimientoFiltro || undefined,
this.ambitoFiltro || undefined,
this.ipsFiltro || undefined
)
.pipe(
finalize(() => {
this.actualizandoAutorizanteMasivo = false;
this.cdr.detectChanges();
})
)
.subscribe({
next: (resp) => {
const total = resp?.actualizados ?? 0;
if (total > 0) {
const nombreMostrado = autorizadoNombre || autorizadoLabel;
this.autorizaciones = this.autorizaciones.map((aut) => ({
...aut,
nombre_autorizante: nombreMostrado,
numero_documento_autorizante: autorizadoId,
}));
this.aplicarFiltroNumero();
}
this.successMessage = `Se actualizaron ${total} autorizaciones.`;
},
error: (err) => {
console.error(err);
this.errorMessage =
err?.error?.error || 'Error actualizando autorizantes.';
},
});
}
actualizarEstadoEntrega(autorizacion: any, estado: string): void { actualizarEstadoEntrega(autorizacion: any, estado: string): void {
if (!this.puedeGestionarEntrega || !autorizacion) { if (!this.puedeGestionarEntrega || !autorizacion) {
return; return;
@ -579,6 +658,29 @@ export class AutorizacionesPorFechaComponent implements OnInit {
this.successMessage = null; this.successMessage = null;
} }
private cargarAutorizantes(): void {
this.cargandoAutorizantes = true;
const autorizantes$ = this.esAdmin
? this.pacienteService.obtenerAutorizantesAdmin()
: this.pacienteService.obtenerAutorizantes();
autorizantes$
.pipe(
finalize(() => {
this.cargandoAutorizantes = false;
this.cdr.detectChanges();
})
)
.subscribe({
next: (data) => {
this.autorizantes = data || [];
},
error: (err) => {
console.error(err);
this.errorMessage = 'No se pudieron cargar los autorizantes.';
},
});
}
// ========= GETTERS DEL FORM ========= // ========= GETTERS DEL FORM =========
get fecha_inicio() { get fecha_inicio() {
return this.filtroForm.get('fecha_inicio'); return this.filtroForm.get('fecha_inicio');

View File

@ -287,7 +287,10 @@
<div class="ips-helper" *ngIf="verMasIps"> <div class="ips-helper" *ngIf="verMasIps">
Mostrando IPS de todos los departamentos. Mostrando IPS de todos los departamentos.
</div> </div>
<div class="ips-traslado" *ngIf="observacionTraslado"> <div
class="ips-traslado"
*ngIf="observacionTraslado && formAutorizacion.tipo_autorizacion !== 'consultas_externas'"
>
Se agregara a observaciones: {{ observacionTraslado }} Se agregara a observaciones: {{ observacionTraslado }}
</div> </div>

View File

@ -268,7 +268,11 @@ export class AutorizacionesComponent {
const deptoIps = String(ipsSeleccionada.departamento || '').trim(); const deptoIps = String(ipsSeleccionada.departamento || '').trim();
const deptoInterno = String(this.departamentoInterno || '').trim(); const deptoInterno = String(this.departamentoInterno || '').trim();
const esConsultaExterna =
String(this.formAutorizacion.tipo_autorizacion || '').toLowerCase() ===
'consultas_externas';
const requiereTraslado = const requiereTraslado =
!esConsultaExterna &&
this.verMasIps && this.verMasIps &&
deptoIps && deptoIps &&
deptoInterno && deptoInterno &&
@ -339,6 +343,13 @@ export class AutorizacionesComponent {
this.formAutorizacion.tipo_servicio = ''; this.formAutorizacion.tipo_servicio = '';
this.limpiarArchivosHospitalarios(); this.limpiarArchivosHospitalarios();
} }
const esConsultaExterna =
String(this.formAutorizacion.tipo_autorizacion || '').toLowerCase() ===
'consultas_externas';
if (esConsultaExterna) {
this.observacionTraslado = '';
}
this.onIpsChange();
} }
onTipoServicioChange(): void { onTipoServicioChange(): void {
@ -675,7 +686,11 @@ export class AutorizacionesComponent {
baseSinTraslado = baseSinTraslado.replace(trasladoRegex, '').trim(); baseSinTraslado = baseSinTraslado.replace(trasladoRegex, '').trim();
} }
if (!trasladoTexto) { const esConsultaExterna =
String(this.formAutorizacion.tipo_autorizacion || '').toLowerCase() ===
'consultas_externas';
if (!trasladoTexto || esConsultaExterna) {
return baseSinTraslado || undefined; return baseSinTraslado || undefined;
} }

View File

@ -422,4 +422,35 @@ export class PacienteService {
); );
} }
actualizarAutorizanteMasivo(
fechaInicio: string,
fechaFin: string,
numeroDocumentoAutorizante: number,
establecimiento?: string,
ambito?: string,
ips?: string
): Observable<any> {
const payload: any = {
fecha_inicio: fechaInicio,
fecha_fin: fechaFin,
numero_documento_autorizante: numeroDocumentoAutorizante,
};
if (establecimiento) {
payload.establecimiento = establecimiento;
}
if (ambito) {
payload.ambito = ambito;
}
if (ips) {
payload.ips = ips;
}
return this.http.patch(
`${this.API_URL}/autorizaciones/autorizante-masivo`,
payload,
{ headers: this.getAuthHeaders() }
);
}
} }