Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
99 lines
4.3 KiB
PHP
99 lines
4.3 KiB
PHP
<?php
|
|
/**
|
|
* POST /api/lab/save_paciente.php
|
|
* Crea o actualiza un paciente.
|
|
* Body JSON:
|
|
* { id?, nombre_completo, numero_documento?, tipo_documento?, telefono?,
|
|
* email?, fecha_nacimiento?, genero?, direccion?, ciudad?, barrio?,
|
|
* eps?, notas_admin?, user_id? }
|
|
*/
|
|
require_once __DIR__ . '/_helpers.php';
|
|
requireMethod('POST');
|
|
|
|
try {
|
|
$datos = inputJson();
|
|
|
|
// user_id vacío → null para evitar error de tipo en la BD
|
|
if (isset($datos['user_id']) && $datos['user_id'] === '') {
|
|
$datos['user_id'] = null;
|
|
}
|
|
|
|
// ── Validación de formato de campos del paciente ────────────────────────
|
|
$nombreVal = trim($datos['nombre_completo'] ?? '');
|
|
if ($nombreVal !== '') {
|
|
if (!preg_match('/^[\p{L}\s\'\-\.]+$/u', $nombreVal)) {
|
|
jsonError('El nombre solo debe contener letras, tildes y espacios (sin números ni símbolos).');
|
|
}
|
|
if (count(preg_split('/\s+/', $nombreVal, -1, PREG_SPLIT_NO_EMPTY)) < 2) {
|
|
jsonError('Ingresa el nombre completo: nombre y apellido (mínimo 2 palabras).');
|
|
}
|
|
}
|
|
$telVal = trim($datos['telefono'] ?? '');
|
|
if ($telVal !== '') {
|
|
$telDigits = preg_replace('/[^0-9]/', '', $telVal);
|
|
// Número colombiano: 10 dígitos empezando en 3, o con prefijo 57
|
|
$esColombia = preg_match('/^57/', $telDigits) || (strlen($telDigits) === 10 && $telDigits[0] === '3');
|
|
if ($esColombia) {
|
|
$sinPrefijo = preg_replace('/^57/', '', $telDigits);
|
|
if (!preg_match('/^3\d{9}$/', $sinPrefijo)) {
|
|
jsonError('El celular colombiano debe comenzar por 3 y tener 10 dígitos. Ej: 3001234567.');
|
|
}
|
|
} elseif (strlen($telDigits) < 6 || strlen($telDigits) > 15) {
|
|
jsonError('El número telefónico no es válido (debe tener entre 6 y 15 dígitos).');
|
|
}
|
|
}
|
|
$docVal = trim($datos['numero_documento'] ?? '');
|
|
$tipoDoc = trim($datos['tipo_documento'] ?? 'CC');
|
|
if ($docVal !== '' && in_array($tipoDoc, ['CC', 'TI', 'RC', 'CE'], true)) {
|
|
$docDigits = preg_replace('/[^0-9]/', '', $docVal);
|
|
if (strlen($docDigits) < 4 || strlen($docDigits) > 12) {
|
|
jsonError('La cédula/TI/RC/CE debe tener entre 4 y 12 dígitos numéricos.');
|
|
}
|
|
}
|
|
$emailVal = trim($datos['email'] ?? '');
|
|
if ($emailVal !== '' && !filter_var($emailVal, FILTER_VALIDATE_EMAIL)) {
|
|
jsonError('El correo electrónico no es válido. Ej: nombre@dominio.com.');
|
|
}
|
|
// ────────────────────────────────────────────────────────────────────────
|
|
|
|
// Auto-vincular user_id por teléfono si no viene explícito
|
|
if (empty($datos['user_id']) && !empty($telVal)) {
|
|
$pdo = db();
|
|
$stmt = $pdo->prepare("SELECT id FROM users WHERE phone_number = ? LIMIT 1");
|
|
$stmt->execute([$telVal]);
|
|
$wid = $stmt->fetchColumn();
|
|
if ($wid) $datos['user_id'] = (int)$wid;
|
|
}
|
|
|
|
$pac = new Paciente();
|
|
$admin = adminId();
|
|
|
|
if (!empty($datos['id'])) {
|
|
// Actualización
|
|
$id = (int)$datos['id'];
|
|
unset($datos['id']);
|
|
$pac->actualizar($id, $datos, $admin);
|
|
jsonOk(['id' => $id], 'Paciente actualizado correctamente');
|
|
} else {
|
|
// Creación — nombre obligatorio
|
|
if (empty($datos['nombre_completo'])) {
|
|
jsonError('El campo nombre_completo es obligatorio');
|
|
}
|
|
$id = $pac->crear($datos, $admin);
|
|
jsonOk(['id' => $id], 'Paciente creado correctamente');
|
|
}
|
|
} catch (Exception $e) {
|
|
$msg = $e->getMessage();
|
|
// Traducir errores de clave duplicada que hayan escapado la validación previa
|
|
if (stripos($msg, 'Duplicate entry') !== false || stripos($msg, '1062') !== false) {
|
|
if (stripos($msg, 'numero_documento') !== false || stripos($msg, 'documento') !== false) {
|
|
jsonError('Ya existe un paciente con ese número de documento');
|
|
}
|
|
if (stripos($msg, 'email') !== false) {
|
|
jsonError('Ya existe un paciente con ese correo electrónico');
|
|
}
|
|
jsonError('Ya existe un registro con esos datos (valor duplicado)');
|
|
}
|
|
jsonError($msg, 400);
|
|
}
|