getConnection()->prepare( "SELECT td.lugar_id, td.nombre, tl.tipo FROM turnero_dispositivos td JOIN turnero_lugares tl ON tl.id = td.lugar_id WHERE td.ip = ? AND td.activo = 1 LIMIT 1" ); $_dispStmt->execute([$clientIp]); $_disp = $_dispStmt->fetch(PDO::FETCH_ASSOC); if ($_disp) { $_SESSION['turnero_dispositivo'] = $_disp; $url = $_disp['tipo'] === 'recepcion' ? BASE_URL . 'erp.php?m=turnero&v=recepcion&desk_id=' . $_disp['lugar_id'] : BASE_URL . 'erp.php?m=turnero&v=lugar&lugar_id=' . $_disp['lugar_id']; header('Location: ' . $url); exit; } } catch (\Throwable $_) {} $roleSlug = $adminUser['role'] ?? 'admin'; $modules = $adminUser['modules'] ?? []; if (!empty($adminUser['home_page'])) { $safePath = filter_var($adminUser['home_page'], FILTER_SANITIZE_URL); if (str_starts_with($safePath, '/') && !str_starts_with($safePath, '//')) { header('Location: ' . $safePath); exit; } } // Usuario con lugar fijo asignado (sin IP registrada) $_userLugarId = (int)($adminUser['turnero_lugar_id'] ?? 0); if ($_userLugarId && in_array('turnero', $modules, true)) { // Determinar si ese lugar es recepción o toma de muestras try { $_lugarTipo = Database::getInstance()->getConnection() ->prepare("SELECT tipo FROM turnero_lugares WHERE id = ? LIMIT 1"); $_lugarTipo->execute([$_userLugarId]); $_tipo = $_lugarTipo->fetchColumn() ?: 'muestras'; } catch (\Throwable $_) { $_tipo = 'muestras'; } $url = $_tipo === 'recepcion' ? BASE_URL . 'erp.php?m=turnero&v=recepcion&desk_id=' . $_userLugarId : BASE_URL . 'erp.php?m=turnero&v=lugar&lugar_id=' . $_userLugarId; header('Location: ' . $url); exit; } if ($roleSlug === 'enfermero') { header('Location: enfermero_portal.php'); } elseif (in_array('turnero', $modules, true)) { header('Location: erp.php?m=turnero&v=recepcion'); } elseif (in_array('lab_dashboard', $modules, true)) { header('Location: lab_dashboard.php'); } elseif (in_array('lab_formularios', $modules, true)) { header('Location: lab_formularios.php'); } elseif (in_array('lab_ordenes', $modules, true)) { header('Location: lab_ordenes.php'); } elseif (in_array('whatsapp', $modules, true)) { header('Location: index.php'); } else { header('Location: index.php'); } exit; } else { recordFailedLogin($clientIp); $error = 'Usuario o contraseña incorrectos.'; if (!checkLoginAttempts($clientIp)) { $loginBlocked = true; $error = 'Demasiados intentos de login. Cuenta bloqueada por ' . (LOGIN_LOCKOUT_TIME / 60) . ' minutos.'; } } } // ── Cargar configuración de la empresa para el branding ──────────────────── $cfg = []; try { $db = Database::getInstance(); $rows = $db->fetchAll('SELECT clave, valor FROM lab_config ORDER BY clave'); foreach ($rows as $r) { $cfg[$r['clave']] = $r['valor']; } } catch (Exception $e) { // BD no disponible: continuar con defaults } $empresa = htmlspecialchars($cfg['empresa_nombre'] ?? 'Laboratorio Clínico', ENT_QUOTES, 'UTF-8'); $subtitulo= htmlspecialchars($cfg['empresa_subtitulo'] ?? 'Sistema de Gestión ERP', ENT_QUOTES, 'UTF-8'); $color = preg_match('/^#[0-9a-fA-F]{3,8}$/', $cfg['doc_color'] ?? '') ? $cfg['doc_color'] : '#1565c0'; $logo = $cfg['doc_logo_base64'] ?? ''; // Calcular color derivado más oscuro para el gradiente function adjustColor(string $hex, int $amount): string { $hex = ltrim($hex, '#'); $r = max(0, min(255, hexdec(substr($hex, 0, 2)) + $amount)); $g = max(0, min(255, hexdec(substr($hex, 2, 2)) + $amount)); $b = max(0, min(255, hexdec(substr($hex, 4, 2)) + $amount)); return sprintf('#%02x%02x%02x', $r, $g, $b); } $colorDark = adjustColor($color, -40); ?>
Bienvenido
Inicia sesión en el sistema ERP