149 lines
5.2 KiB
PHP
149 lines
5.2 KiB
PHP
<?php
|
|
/**
|
|
* modules/registro_exams/api/save_orden.php
|
|
* POST — crea o actualiza una orden de examen.
|
|
*
|
|
* Body JSON:
|
|
* {
|
|
* "id": null | int, // null = nueva / int = editar
|
|
* "paciente_id": int, // requerido
|
|
* "solicitud_id": null | int,
|
|
* "orden_medica_id": null | int,
|
|
* "medico_nombre": string,
|
|
* "medico_registro": string,
|
|
* "diagnostico": string,
|
|
* "prioridad": "normal"|"urgente"|"stat",
|
|
* "notas": string,
|
|
* "items": [int, int, ...] // exam_tipo_id[]
|
|
* }
|
|
*
|
|
* Respuesta exitosa:
|
|
* { ok: true, id: <orden_id>, codigo: "EX-YYYYMMDD-NNNN" }
|
|
*/
|
|
|
|
require_once __DIR__ . '/_helpers.php';
|
|
requireMethod('POST');
|
|
requireExams();
|
|
|
|
$body = inputJson();
|
|
|
|
// ── Validaciones ──────────────────────────────────────────────
|
|
$pacienteId = isset($body['paciente_id']) ? (int) $body['paciente_id'] : 0;
|
|
if ($pacienteId <= 0) {
|
|
jsonError('Debe indicar el paciente (paciente_id)');
|
|
}
|
|
|
|
$items = isset($body['items']) && is_array($body['items'])
|
|
? array_map('intval', $body['items'])
|
|
: [];
|
|
|
|
// Filtrar zeros
|
|
$items = array_values(array_filter($items, fn($v) => $v > 0));
|
|
if (count($items) === 0) {
|
|
jsonError('Debe agregar al menos un examen');
|
|
}
|
|
|
|
// Normalizar prioridad
|
|
$prioridadesPermitidas = ['normal', 'urgente', 'stat'];
|
|
$prioridad = in_array($body['prioridad'] ?? '', $prioridadesPermitidas, true)
|
|
? $body['prioridad'] : 'normal';
|
|
|
|
$ordenId = isset($body['id']) && $body['id'] ? (int) $body['id'] : null;
|
|
$solicitudId = isset($body['solicitud_id']) ? ((int) $body['solicitud_id'] ?: null) : null;
|
|
$ordenMedId = isset($body['orden_medica_id']) ? ((int) $body['orden_medica_id'] ?: null) : null;
|
|
$medicoNombre = trim($body['medico_nombre'] ?? '');
|
|
$medicoReg = trim($body['medico_registro'] ?? '');
|
|
$diagnostico = trim($body['diagnostico'] ?? '');
|
|
$notas = trim($body['notas'] ?? '');
|
|
|
|
$pdo = db();
|
|
|
|
try {
|
|
$pdo->beginTransaction();
|
|
|
|
if ($ordenId === null) {
|
|
// ── CREAR nueva orden ──────────────────────────────────
|
|
$codigo = generarCodigoOrden();
|
|
|
|
$stmt = $pdo->prepare('
|
|
INSERT INTO exam_ordenes
|
|
(paciente_id, solicitud_id, orden_medica_id, codigo,
|
|
medico_nombre, medico_registro, diagnostico,
|
|
prioridad, notas, creado_por, creado_at)
|
|
VALUES
|
|
(?, ?, ?, ?,
|
|
?, ?, ?,
|
|
?, ?, ?, NOW())
|
|
');
|
|
$stmt->execute([
|
|
$pacienteId, $solicitudId, $ordenMedId, $codigo,
|
|
$medicoNombre ?: null, $medicoReg ?: null, $diagnostico ?: null,
|
|
$prioridad, $notas ?: null, adminId(),
|
|
]);
|
|
$ordenId = (int) $pdo->lastInsertId();
|
|
|
|
} else {
|
|
// ── ACTUALIZAR orden existente ─────────────────────────
|
|
$stmt = $pdo->prepare('
|
|
UPDATE exam_ordenes SET
|
|
medico_nombre = ?,
|
|
medico_registro = ?,
|
|
diagnostico = ?,
|
|
prioridad = ?,
|
|
notas = ?,
|
|
updated_at = NOW()
|
|
WHERE id = ?
|
|
');
|
|
$stmt->execute([
|
|
$medicoNombre ?: null, $medicoReg ?: null, $diagnostico ?: null,
|
|
$prioridad, $notas ?: null, $ordenId,
|
|
]);
|
|
|
|
// Leer código actual para devolverlo
|
|
$stmt2 = $pdo->prepare('SELECT codigo FROM exam_ordenes WHERE id = ?');
|
|
$stmt2->execute([$ordenId]);
|
|
$codigo = $stmt2->fetchColumn() ?: '';
|
|
}
|
|
|
|
// ── Sincronizar ítems ──────────────────────────────────────
|
|
// Obtener tipos ya existentes en la orden
|
|
$stmtEx = $pdo->prepare(
|
|
'SELECT exam_tipo_id FROM exam_items WHERE orden_id = ?'
|
|
);
|
|
$stmtEx->execute([$ordenId]);
|
|
$existentes = array_column($stmtEx->fetchAll(PDO::FETCH_ASSOC), 'exam_tipo_id');
|
|
$existentes = array_map('intval', $existentes);
|
|
|
|
// Insertar los que no existen aún
|
|
$nuevos = array_diff($items, $existentes);
|
|
if ($nuevos) {
|
|
$stmtIns = $pdo->prepare(
|
|
'INSERT INTO exam_items (orden_id, exam_tipo_id) VALUES (?, ?)'
|
|
);
|
|
foreach ($nuevos as $tipoId) {
|
|
$stmtIns->execute([$ordenId, $tipoId]);
|
|
}
|
|
}
|
|
|
|
// Eliminar los que ya no están en la lista (solo si aún están pendientes)
|
|
$eliminar = array_diff($existentes, $items);
|
|
if ($eliminar) {
|
|
$inPlaceholders = implode(',', array_fill(0, count($eliminar), '?'));
|
|
$stmtDel = $pdo->prepare(
|
|
"DELETE FROM exam_items
|
|
WHERE orden_id = ?
|
|
AND exam_tipo_id IN ({$inPlaceholders})
|
|
AND estado = 'pendiente'"
|
|
);
|
|
$stmtDel->execute(array_merge([$ordenId], array_values($eliminar)));
|
|
}
|
|
|
|
$pdo->commit();
|
|
|
|
jsonOk(['id' => $ordenId, 'codigo' => $codigo], 'Orden guardada correctamente');
|
|
|
|
} catch (\Throwable $e) {
|
|
$pdo->rollBack();
|
|
jsonError('Error al guardar la orden: ' . $e->getMessage(), 500);
|
|
}
|