mas cambios 2
This commit is contained in:
parent
b8c258a963
commit
6ace09ec6c
@ -2539,7 +2539,11 @@ async function crearLibroAutorizacion(a) {
|
||||
sheet.mergeCells('O35:R35');
|
||||
sheet.mergeCells('B24:R24');
|
||||
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('B31:G32');
|
||||
sheet.mergeCells('H31:R31');
|
||||
@ -2658,6 +2662,32 @@ async function crearLibroAutorizacion(a) {
|
||||
.replace(/\s+/g, ' ')
|
||||
.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)
|
||||
['F8', 'G8', 'H8', 'I8'].forEach(celda => {
|
||||
sheet.getCell(celda).value = a.numero_autorizacion || '';
|
||||
@ -2692,12 +2722,12 @@ async function crearLibroAutorizacion(a) {
|
||||
sheet.getCell(celda).value = nombreIps;
|
||||
});
|
||||
|
||||
const nitIps = a.nit || '';
|
||||
const nitIps = cleanIpsValue(a.nit);
|
||||
['D13', 'E13', 'F13', 'G13'].forEach(celda => {
|
||||
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 => {
|
||||
sheet.getCell(celda).value = telefonoIps;
|
||||
});
|
||||
@ -2710,8 +2740,9 @@ async function crearLibroAutorizacion(a) {
|
||||
});
|
||||
|
||||
// 5) Dirección IPS (M16:N16)
|
||||
const direccionIps = cleanIpsValue(a.direccion);
|
||||
['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 => {
|
||||
@ -2719,12 +2750,12 @@ async function crearLibroAutorizacion(a) {
|
||||
});
|
||||
|
||||
['M16', 'N16'].forEach(celda => {
|
||||
sheet.getCell(celda).value = a.municipio || '';
|
||||
sheet.getCell(celda).value = cleanIpsValue(a.municipio);
|
||||
});
|
||||
|
||||
// 6) Departamento IPS (Q16:R16)
|
||||
['Q16', 'R16'].forEach(celda => {
|
||||
sheet.getCell(celda).value = a.departamento || '';
|
||||
sheet.getCell(celda).value = cleanIpsValue(a.departamento);
|
||||
});
|
||||
|
||||
// 7) Nombre completo paciente (H18:R18)
|
||||
@ -2742,10 +2773,36 @@ async function crearLibroAutorizacion(a) {
|
||||
sheet.getCell(celda).value = a.numero_documento || '';
|
||||
});
|
||||
|
||||
['H27','R27'].forEach(celda => {
|
||||
['H29','R29'].forEach(celda => {
|
||||
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)
|
||||
const cupCodigo = a.cup_codigo || '';
|
||||
const cupDescripcion = a.cup_descripcion || '';
|
||||
@ -2773,13 +2830,34 @@ async function crearLibroAutorizacion(a) {
|
||||
});
|
||||
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 observacionLower = observacionBase.toLowerCase();
|
||||
const solicitanteInfo =
|
||||
solicitanteNombre && !observacionLower.includes('solicitante')
|
||||
? `Solicitante: ${solicitanteNombre}`
|
||||
: '';
|
||||
esConsultaExterna
|
||||
? ''
|
||||
: solicitanteNombre && !observacionLower.includes('solicitante')
|
||||
? `Solicitante: ${solicitanteNombre}`
|
||||
: '';
|
||||
const observacion = [cupInfo, observacionBase, solicitanteInfo]
|
||||
.filter(Boolean)
|
||||
.join(' | ');
|
||||
|
||||
@ -2338,6 +2338,32 @@ async function crearLibroAutorizacionBrigadasAmbulanciasHospitalarios(a) {
|
||||
.replace(/\s+/g, ' ')
|
||||
.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) => {
|
||||
sheet.getCell(celda).value = a.numero_autorizacion || '';
|
||||
});
|
||||
@ -2368,12 +2394,12 @@ async function crearLibroAutorizacionBrigadasAmbulanciasHospitalarios(a) {
|
||||
sheet.getCell(celda).value = nombreIps;
|
||||
});
|
||||
|
||||
const nitIps = a.nit || '';
|
||||
const nitIps = cleanIpsValue(a.nit);
|
||||
['D13', 'E13', 'F13', 'G13'].forEach((celda) => {
|
||||
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) => {
|
||||
sheet.getCell(celda).value = telefonoIps;
|
||||
});
|
||||
@ -2385,8 +2411,9 @@ async function crearLibroAutorizacionBrigadasAmbulanciasHospitalarios(a) {
|
||||
sheet.getCell(celda).value = a.sexo || '';
|
||||
});
|
||||
|
||||
const direccionIps = cleanIpsValue(a.direccion);
|
||||
['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) => {
|
||||
@ -2394,11 +2421,11 @@ async function crearLibroAutorizacionBrigadasAmbulanciasHospitalarios(a) {
|
||||
});
|
||||
|
||||
['M16', 'N16'].forEach((celda) => {
|
||||
sheet.getCell(celda).value = a.municipio || '';
|
||||
sheet.getCell(celda).value = cleanIpsValue(a.municipio);
|
||||
});
|
||||
|
||||
['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) => {
|
||||
|
||||
@ -1507,6 +1507,28 @@ const normalizeDigits = (value) => String(value || '').replace(/\D/g, '');
|
||||
const normalizeNameKey = (value) =>
|
||||
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 text = String(value || '').trim();
|
||||
if (!text) return '';
|
||||
@ -1667,19 +1689,18 @@ async function procesarExcelIps(inputFilePath) {
|
||||
|
||||
for (let i = 2; i <= sheet.rowCount; i++) {
|
||||
const row = sheet.getRow(i);
|
||||
const nit = getValueMulti(row, [
|
||||
'NIT',
|
||||
'NITIPS',
|
||||
'NITPRESTADOR',
|
||||
'NITPRESTADORIPS',
|
||||
]);
|
||||
const nombre = getValueMulti(row, [
|
||||
'PRESTADOR',
|
||||
'PRESTADORDELSERVICIO',
|
||||
'PRESTADORDESERVICIO',
|
||||
'NOMBREPRESTADOR',
|
||||
'NOMBREIPS',
|
||||
]);
|
||||
const nit = cleanIpsField(
|
||||
getValueMulti(row, ['NIT', 'NITIPS', 'NITPRESTADOR', 'NITPRESTADORIPS'])
|
||||
);
|
||||
const nombre = cleanIpsField(
|
||||
getValueMulti(row, [
|
||||
'PRESTADOR',
|
||||
'PRESTADORDELSERVICIO',
|
||||
'PRESTADORDESERVICIO',
|
||||
'NOMBREPRESTADOR',
|
||||
'NOMBREIPS',
|
||||
])
|
||||
);
|
||||
|
||||
if (!nit && !nombre) {
|
||||
continue;
|
||||
@ -1687,15 +1708,13 @@ async function procesarExcelIps(inputFilePath) {
|
||||
|
||||
resumen.total += 1;
|
||||
|
||||
const direccion = getValue(row, 'DIRECCION');
|
||||
const departamento = getValue(row, 'DEPARTAMENTO');
|
||||
const municipio = getValue(row, 'MUNICIPIO');
|
||||
const telefono = getValue(row, 'TELEFONO');
|
||||
const codigoIps = getValueMulti(row, [
|
||||
'CODIGOIPS',
|
||||
'CODIGOPRESTADOR',
|
||||
'CODIGOHABILITACION',
|
||||
]);
|
||||
const direccion = cleanIpsField(getValue(row, 'DIRECCION'));
|
||||
const departamento = cleanIpsField(getValue(row, 'DEPARTAMENTO'));
|
||||
const municipio = cleanIpsField(getValue(row, 'MUNICIPIO'));
|
||||
const telefono = cleanIpsField(getValue(row, 'TELEFONO'));
|
||||
const codigoIps = cleanIpsField(
|
||||
getValueMulti(row, ['CODIGOIPS', 'CODIGOPRESTADOR', 'CODIGOHABILITACION'])
|
||||
);
|
||||
|
||||
const nitDigits = registerDigits(nitKeys, nit);
|
||||
const codigoDigits = registerDigits(codigoKeys, codigoIps);
|
||||
@ -1777,16 +1796,18 @@ async function procesarExcelIps(inputFilePath) {
|
||||
await client.query(
|
||||
`
|
||||
UPDATE ips
|
||||
SET nombre_ips = COALESCE($1, nombre_ips),
|
||||
codigo_ips = COALESCE($2, codigo_ips),
|
||||
direccion = COALESCE($3, direccion),
|
||||
telefono = COALESCE($4, telefono),
|
||||
departamento = COALESCE($5, departamento),
|
||||
municipio = COALESCE($6, municipio),
|
||||
SET nit = COALESCE($1, nit),
|
||||
nombre_ips = COALESCE($2, nombre_ips),
|
||||
codigo_ips = COALESCE($3, codigo_ips),
|
||||
direccion = COALESCE($4, direccion),
|
||||
telefono = COALESCE($5, telefono),
|
||||
departamento = COALESCE($6, departamento),
|
||||
municipio = COALESCE($7, municipio),
|
||||
tiene_convenio = true
|
||||
WHERE id_ips = $7
|
||||
WHERE id_ips = $8
|
||||
`,
|
||||
[
|
||||
nit || null,
|
||||
nombre || null,
|
||||
codigoIps || 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
|
||||
* Query params: fecha_inicio, fecha_fin
|
||||
|
||||
@ -242,6 +242,36 @@
|
||||
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-container {
|
||||
overflow-x: auto;
|
||||
@ -503,6 +533,11 @@
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.autorizante-masivo {
|
||||
width: 100%;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.autorizaciones-table th,
|
||||
.autorizaciones-table td {
|
||||
padding: 8px 12px;
|
||||
@ -527,7 +562,9 @@
|
||||
.btn-exportar,
|
||||
.btn-descargar-todos,
|
||||
.estado-masivo,
|
||||
.estado-masivo button {
|
||||
.estado-masivo button,
|
||||
.autorizante-masivo,
|
||||
.autorizante-masivo button {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
@ -537,11 +574,22 @@
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.autorizante-masivo {
|
||||
width: 100%;
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.estado-masivo select,
|
||||
.estado-masivo button {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.autorizante-masivo select,
|
||||
.autorizante-masivo button {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.empty-state {
|
||||
padding: 40px 16px;
|
||||
}
|
||||
|
||||
@ -149,6 +149,32 @@
|
||||
{{ actualizandoMasivo ? 'Actualizando...' : 'Aplicar a todo el rango' }}
|
||||
</button>
|
||||
</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
|
||||
class="btn btn-secondary btn-exportar"
|
||||
*ngIf="puedeDescargarMasivo"
|
||||
|
||||
@ -27,6 +27,7 @@ export class AutorizacionesPorFechaComponent implements OnInit {
|
||||
actualizandoEstado: Record<string, boolean> = {};
|
||||
actualizandoMasivo = false;
|
||||
estadoMasivo: 'pendiente' | 'autorizado' | 'no_autorizado' = 'autorizado';
|
||||
actualizandoAutorizanteMasivo = false;
|
||||
esAdmin = false;
|
||||
puedeGestionarEntrega = false;
|
||||
puedeDescargarMasivo = false;
|
||||
@ -36,6 +37,9 @@ export class AutorizacionesPorFechaComponent implements OnInit {
|
||||
ipsFiltro = '';
|
||||
autorizacionesFiltradas: any[] = [];
|
||||
actualizandoEntrega: Record<string, boolean> = {};
|
||||
autorizantes: any[] = [];
|
||||
autorizanteMasivo = '';
|
||||
cargandoAutorizantes = false;
|
||||
|
||||
// Para saber si ya buscamos algo
|
||||
hayResultados = false;
|
||||
@ -67,6 +71,10 @@ export class AutorizacionesPorFechaComponent implements OnInit {
|
||||
this.esAdmin || this.authService.isAdministrativoSede();
|
||||
this.puedeDescargarMasivo = this.authService.puedeDescargarPdfs();
|
||||
|
||||
if (this.esAdmin) {
|
||||
this.cargarAutorizantes();
|
||||
}
|
||||
|
||||
// Rango por defecto: últimos 30 días
|
||||
const hoy = new Date();
|
||||
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 {
|
||||
if (!this.puedeGestionarEntrega || !autorizacion) {
|
||||
return;
|
||||
@ -579,6 +658,29 @@ export class AutorizacionesPorFechaComponent implements OnInit {
|
||||
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 =========
|
||||
get fecha_inicio() {
|
||||
return this.filtroForm.get('fecha_inicio');
|
||||
|
||||
@ -287,7 +287,10 @@
|
||||
<div class="ips-helper" *ngIf="verMasIps">
|
||||
Mostrando IPS de todos los departamentos.
|
||||
</div>
|
||||
<div class="ips-traslado" *ngIf="observacionTraslado">
|
||||
<div
|
||||
class="ips-traslado"
|
||||
*ngIf="observacionTraslado && formAutorizacion.tipo_autorizacion !== 'consultas_externas'"
|
||||
>
|
||||
Se agregara a observaciones: {{ observacionTraslado }}
|
||||
</div>
|
||||
|
||||
|
||||
@ -268,7 +268,11 @@ export class AutorizacionesComponent {
|
||||
|
||||
const deptoIps = String(ipsSeleccionada.departamento || '').trim();
|
||||
const deptoInterno = String(this.departamentoInterno || '').trim();
|
||||
const esConsultaExterna =
|
||||
String(this.formAutorizacion.tipo_autorizacion || '').toLowerCase() ===
|
||||
'consultas_externas';
|
||||
const requiereTraslado =
|
||||
!esConsultaExterna &&
|
||||
this.verMasIps &&
|
||||
deptoIps &&
|
||||
deptoInterno &&
|
||||
@ -339,6 +343,13 @@ export class AutorizacionesComponent {
|
||||
this.formAutorizacion.tipo_servicio = '';
|
||||
this.limpiarArchivosHospitalarios();
|
||||
}
|
||||
const esConsultaExterna =
|
||||
String(this.formAutorizacion.tipo_autorizacion || '').toLowerCase() ===
|
||||
'consultas_externas';
|
||||
if (esConsultaExterna) {
|
||||
this.observacionTraslado = '';
|
||||
}
|
||||
this.onIpsChange();
|
||||
}
|
||||
|
||||
onTipoServicioChange(): void {
|
||||
@ -675,7 +686,11 @@ export class AutorizacionesComponent {
|
||||
baseSinTraslado = baseSinTraslado.replace(trasladoRegex, '').trim();
|
||||
}
|
||||
|
||||
if (!trasladoTexto) {
|
||||
const esConsultaExterna =
|
||||
String(this.formAutorizacion.tipo_autorizacion || '').toLowerCase() ===
|
||||
'consultas_externas';
|
||||
|
||||
if (!trasladoTexto || esConsultaExterna) {
|
||||
return baseSinTraslado || undefined;
|
||||
}
|
||||
|
||||
|
||||
@ -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() }
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user