316 lines
9.7 KiB
PHP
316 lines
9.7 KiB
PHP
<?php
|
|
|
|
/**
|
|
* Validadores de Datos del Paciente
|
|
* Valida información para agendamientos y procesos
|
|
*/
|
|
|
|
class PatientDataValidator
|
|
{
|
|
/**
|
|
* Valida todos los datos del paciente para agendamiento
|
|
* @param array $data
|
|
* @return array ['valid' => bool, 'errors' => array, 'data' => array]
|
|
*/
|
|
public static function validateAppointmentData(array $data): array
|
|
{
|
|
$errors = [];
|
|
$validData = [];
|
|
|
|
// Nombre completo
|
|
if (empty($data['nombre'])) {
|
|
$errors[] = "Falta el nombre completo";
|
|
} elseif (!self::validateFullName($data['nombre'])) {
|
|
$errors[] = "El nombre debe tener al menos nombre y apellido";
|
|
} else {
|
|
$validData['nombre'] = self::sanitizeName($data['nombre']);
|
|
}
|
|
|
|
// Documento
|
|
if (empty($data['documento'])) {
|
|
$errors[] = "Falta el número de documento";
|
|
} elseif (!self::validateDocument($data['documento'])) {
|
|
$errors[] = "El documento debe tener entre 6 y 11 dígitos";
|
|
} else {
|
|
$validData['documento'] = self::sanitizeDocument($data['documento']);
|
|
}
|
|
|
|
// Dirección
|
|
if (empty($data['direccion'])) {
|
|
$errors[] = "Falta la dirección completa";
|
|
} elseif (strlen($data['direccion']) < 10) {
|
|
$errors[] = "La dirección debe ser más específica (mínimo 10 caracteres)";
|
|
} else {
|
|
$validData['direccion'] = trim($data['direccion']);
|
|
}
|
|
|
|
// Teléfono
|
|
if (empty($data['telefono'])) {
|
|
$errors[] = "Falta el número de celular";
|
|
} elseif (!self::validatePhone($data['telefono'])) {
|
|
$errors[] = "El número de celular debe tener 10 dígitos y comenzar con 3";
|
|
} else {
|
|
$validData['telefono'] = self::sanitizePhone($data['telefono']);
|
|
}
|
|
|
|
// Email
|
|
if (empty($data['email'])) {
|
|
$errors[] = "Falta el correo electrónico";
|
|
} elseif (!self::validateEmail($data['email'])) {
|
|
$errors[] = "El correo electrónico no es válido";
|
|
} else {
|
|
$validData['email'] = strtolower(trim($data['email']));
|
|
}
|
|
|
|
// Tipo (particular/seguro)
|
|
if (empty($data['tipo'])) {
|
|
$errors[] = "Falta indicar si es particular o por seguro";
|
|
} else {
|
|
$tipo = strtolower(trim($data['tipo']));
|
|
if (strpos($tipo, 'particular') !== false) {
|
|
$validData['tipo'] = 'particular';
|
|
} elseif (strpos($tipo, 'seguro') !== false || strpos($tipo, 'eps') !== false) {
|
|
$validData['tipo'] = 'seguro';
|
|
// Extraer nombre del seguro si lo menciona
|
|
$validData['nombre_seguro'] = self::extractInsuranceName($data['tipo']);
|
|
} else {
|
|
$errors[] = "Debe indicar 'particular' o 'seguro'";
|
|
}
|
|
}
|
|
|
|
return [
|
|
'valid' => empty($errors),
|
|
'errors' => $errors,
|
|
'data' => $validData
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Valida un nombre completo
|
|
* @param string $name
|
|
* @return bool
|
|
*/
|
|
public static function validateFullName(string $name): bool
|
|
{
|
|
$name = trim($name);
|
|
|
|
// Debe tener al menos 2 palabras
|
|
$words = preg_split('/\s+/', $name);
|
|
if (count($words) < 2) {
|
|
return false;
|
|
}
|
|
|
|
// Solo debe contener letras y espacios
|
|
return preg_match('/^[a-záéíóúñA-ZÁÉÍÓÚÑ\s]+$/u', $name);
|
|
}
|
|
|
|
/**
|
|
* Valida un número de documento
|
|
* @param string $document
|
|
* @return bool
|
|
*/
|
|
public static function validateDocument(string $document): bool
|
|
{
|
|
$doc = preg_replace('/[^0-9]/', '', $document);
|
|
$length = strlen($doc);
|
|
|
|
return $length >= 6 && $length <= 11;
|
|
}
|
|
|
|
/**
|
|
* Valida un número de teléfono colombiano
|
|
* @param string $phone
|
|
* @return bool
|
|
*/
|
|
public static function validatePhone(string $phone): bool
|
|
{
|
|
$phone = preg_replace('/[^0-9]/', '', $phone);
|
|
|
|
// Debe tener 10 dígitos y comenzar con 3
|
|
return strlen($phone) === 10 && $phone[0] === '3';
|
|
}
|
|
|
|
/**
|
|
* Valida un correo electrónico
|
|
* @param string $email
|
|
* @return bool
|
|
*/
|
|
public static function validateEmail(string $email): bool
|
|
{
|
|
return filter_var($email, FILTER_VALIDATE_EMAIL) !== false;
|
|
}
|
|
|
|
/**
|
|
* Sanitiza un nombre
|
|
* @param string $name
|
|
* @return string
|
|
*/
|
|
public static function sanitizeName(string $name): string
|
|
{
|
|
// Convertir a formato título (Primera Letra Mayúscula)
|
|
$name = mb_convert_case(trim($name), MB_CASE_TITLE, 'UTF-8');
|
|
|
|
// Remover espacios extras
|
|
$name = preg_replace('/\s+/', ' ', $name);
|
|
|
|
return $name;
|
|
}
|
|
|
|
/**
|
|
* Sanitiza un documento
|
|
* @param string $document
|
|
* @return string
|
|
*/
|
|
public static function sanitizeDocument(string $document): string
|
|
{
|
|
return preg_replace('/[^0-9]/', '', $document);
|
|
}
|
|
|
|
/**
|
|
* Sanitiza un teléfono
|
|
* @param string $phone
|
|
* @return string
|
|
*/
|
|
public static function sanitizePhone(string $phone): string
|
|
{
|
|
$phone = preg_replace('/[^0-9]/', '', $phone);
|
|
|
|
// Si tiene 13 dígitos y empieza con 57, quitar el 57
|
|
if (strlen($phone) === 12 && substr($phone, 0, 2) === '57') {
|
|
$phone = substr($phone, 2);
|
|
}
|
|
|
|
return $phone;
|
|
}
|
|
|
|
/**
|
|
* Extrae el nombre del seguro del texto
|
|
* @param string $text
|
|
* @return string|null
|
|
*/
|
|
private static function extractInsuranceName(string $text): ?string
|
|
{
|
|
$insurances = [
|
|
'colsanitas' => 'Colsanitas',
|
|
'sanitas' => 'Sanitas',
|
|
'sura' => 'Sura',
|
|
'compensar' => 'Compensar',
|
|
'salud total' => 'Salud Total',
|
|
'famisanar' => 'Famisanar',
|
|
'nueva eps' => 'Nueva EPS',
|
|
'coomeva' => 'Coomeva'
|
|
];
|
|
|
|
$textLower = strtolower($text);
|
|
|
|
foreach ($insurances as $key => $name) {
|
|
if (strpos($textLower, $key) !== false) {
|
|
return $name;
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Parsea datos del paciente desde un mensaje de texto
|
|
* @param string $message
|
|
* @return array
|
|
*/
|
|
public static function parsePatientDataFromMessage(string $message): array
|
|
{
|
|
$data = [];
|
|
|
|
// Dividir por líneas
|
|
$lines = explode("\n", $message);
|
|
|
|
foreach ($lines as $line) {
|
|
$line = trim($line);
|
|
|
|
if (empty($line)) {
|
|
continue;
|
|
}
|
|
|
|
// Detectar nombre (primera línea larga con letras)
|
|
if (empty($data['nombre']) && preg_match('/^[a-záéíóúñA-ZÁÉÍÓÚÑ\s]{5,}$/u', $line)) {
|
|
$data['nombre'] = $line;
|
|
continue;
|
|
}
|
|
|
|
// Detectar documento (números de 6-11 dígitos)
|
|
if (empty($data['documento']) && preg_match('/(\d{6,11})/', $line, $matches)) {
|
|
$data['documento'] = $matches[1];
|
|
continue;
|
|
}
|
|
|
|
// Detectar teléfono (10 dígitos comenzando con 3)
|
|
if (empty($data['telefono']) && preg_match('/(3\d{9})/', $line, $matches)) {
|
|
$data['telefono'] = $matches[1];
|
|
continue;
|
|
}
|
|
|
|
// Detectar email
|
|
if (empty($data['email']) && preg_match('/([a-zA-Z0-9._-]+@[a-zA-Z0-9._-]+\.[a-zA-Z]+)/', $line, $matches)) {
|
|
$data['email'] = $matches[1];
|
|
continue;
|
|
}
|
|
|
|
// Detectar dirección (contiene calle, carrera, etc.)
|
|
if (empty($data['direccion']) && preg_match('/(calle|carrera|cra|cl|diagonal|transversal|avenida|av)/i', $line)) {
|
|
$data['direccion'] = $line;
|
|
continue;
|
|
}
|
|
|
|
// Detectar tipo (particular/seguro)
|
|
if (empty($data['tipo']) && preg_match('/(particular|seguro|eps)/i', $line)) {
|
|
$data['tipo'] = $line;
|
|
continue;
|
|
}
|
|
}
|
|
|
|
return $data;
|
|
}
|
|
|
|
/**
|
|
* Genera un mensaje con los errores de validación
|
|
* @param array $errors
|
|
* @return string
|
|
*/
|
|
public static function formatValidationErrors(array $errors): string
|
|
{
|
|
$message = "⚠️ Por favor corrige los siguientes datos:\n\n";
|
|
|
|
foreach ($errors as $error) {
|
|
$message .= "❌ $error\n";
|
|
}
|
|
|
|
$message .= "\nEnvía la información completa de nuevo.";
|
|
|
|
return $message;
|
|
}
|
|
|
|
/**
|
|
* Genera un resumen de los datos validados
|
|
* @param array $data
|
|
* @return string
|
|
*/
|
|
public static function formatDataSummary(array $data): string
|
|
{
|
|
$message = "📋 DATOS RECIBIDOS:\n\n";
|
|
$message .= "👤 Nombre: {$data['nombre']}\n";
|
|
$message .= "🆔 Documento: {$data['documento']}\n";
|
|
$message .= "📍 Dirección: {$data['direccion']}\n";
|
|
$message .= "📱 Teléfono: {$data['telefono']}\n";
|
|
$message .= "📧 Email: {$data['email']}\n";
|
|
$message .= "💳 Tipo: {$data['tipo']}";
|
|
|
|
if (isset($data['nombre_seguro'])) {
|
|
$message .= " ({$data['nombre_seguro']})";
|
|
}
|
|
|
|
$message .= "\n\n¿Los datos son correctos?\nResponde: *SÍ* o *NO*";
|
|
|
|
return $message;
|
|
}
|
|
}
|