From 2f5be9253b2992463c787446791eac1e5cf4e909 Mon Sep 17 00:00:00 2001 From: Lizandro Date: Sat, 18 Jul 2026 16:06:20 +0000 Subject: [PATCH] Fix 5 bugs in chat and Telegram purchase flows MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. PublicChat::comprarPromoConSaldo — double saldo subtraction: $saldo->update() already updates the model in memory, so $this->saldoUsuario = $saldo->valor - precio was subtracting twice. Fixed by computing $nuevoSaldo before the update. Also wrapped in DB::transaction (was missing unlike pagarConSaldo). 2. TelegramBotService::listServices — showed all services without filtering by the user's rol_id, so users could see services with no plans for their role. Now uses whereHas('tarifas', rol_id) like PublicChat and the web. 3. TelegramBotService::payWithSaldo — no DB::transaction; if saldo update failed after historial was created, user got a free service. Now wrapped atomically. 4. TelegramBotService::buyPromoSaldo — same missing transaction + fecha_final was hardcoded to 30 days instead of promo->dias. Both fixed. 5. TelegramBotService::showCredentials — N+1 queries loading cuentas lazily per historial. Added cuentas to the eager-load list. Co-Authored-By: Claude Sonnet 4.6 --- app/Http/Livewire/Chat/PublicChat.php | 13 +++-- app/Services/TelegramBotService.php | 84 ++++++++++++++++----------- 2 files changed, 58 insertions(+), 39 deletions(-) diff --git a/app/Http/Livewire/Chat/PublicChat.php b/app/Http/Livewire/Chat/PublicChat.php index 91e47c3..a72da6a 100755 --- a/app/Http/Livewire/Chat/PublicChat.php +++ b/app/Http/Livewire/Chat/PublicChat.php @@ -909,10 +909,15 @@ class PublicChat extends Component 'nombre_cliente' => $user->name, ]); - Historial_cuenta::create(['historial_id' => $historial->id, 'cuenta_id' => $cuenta->id]); - $cuenta->update(['estado' => 'ocupado']); - $saldo->update(['valor' => $saldo->valor - $precio]); - $this->saldoUsuario = $saldo->valor - $precio; + $nuevoSaldo = $saldo->valor - $precio; + + DB::transaction(function () use ($historial, $cuenta, $saldo, $nuevoSaldo) { + Historial_cuenta::create(['historial_id' => $historial->id, 'cuenta_id' => $cuenta->id]); + $cuenta->update(['estado' => 'ocupado']); + $saldo->update(['valor' => $nuevoSaldo]); + }); + + $this->saldoUsuario = $nuevoSaldo; ChatMessage::create([ 'conversation_id' => $this->convId, diff --git a/app/Services/TelegramBotService.php b/app/Services/TelegramBotService.php index 5c4d5c4..1cd0bf9 100755 --- a/app/Services/TelegramBotService.php +++ b/app/Services/TelegramBotService.php @@ -24,6 +24,7 @@ use App\Models\Tarifas; use App\Models\User; use Carbon\Carbon; use Illuminate\Support\Facades\Cache; +use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Hash; use Illuminate\Support\Facades\Http; use Illuminate\Support\Facades\Log; @@ -611,7 +612,15 @@ class TelegramBotService private function listServices(string $chatId): void { - $servicios = Servicio::where('estado', 'activo')->orderBy('ubicacion')->get(); + $state = $this->getState($chatId); + $rolId = isset($state['user_id']) + ? (User::find($state['user_id'])?->rol_id ?? Role::where('nombre', 'cliente')->value('id')) + : Role::where('nombre', 'cliente')->value('id'); + + $servicios = Servicio::where('estado', 'activo') + ->whereHas('tarifas', fn ($q) => $q->where('estado', 'activo')->where('rol_id', $rolId)) + ->orderBy('ubicacion') + ->get(); if ($servicios->isEmpty()) { $this->send($chatId, "No hay servicios disponibles en este momento."); @@ -736,23 +745,25 @@ class TelegramBotService return; } - $historial = Historiale::create([ - 'fecha_inicio' => now(), - 'fecha_final' => now()->addDays($tarifa->dias), - 'valor' => $precio, - 'utilidad' => $tarifa->utilidad ?? 0, - 'tipo_pago' => 'saldo', - 'estado' => 'entregado', - 'vendedor_id' => $state['user_id'], - 'tarifa_id' => $tarifa->id, - 'cliente_id' => $state['user_id'], - 'nombre_cliente' => $user->name, - ]); - - Historial_cuenta::create(['historial_id' => $historial->id, 'cuenta_id' => $cuenta->id]); - $cuenta->update(['estado' => 'ocupado']); $nuevoSaldo = $saldo->valor - $precio; - $saldo->update(['valor' => $nuevoSaldo]); + + DB::transaction(function () use ($tarifa, $user, $saldo, $cuenta, $precio, $nuevoSaldo, $state) { + $historial = Historiale::create([ + 'fecha_inicio' => now(), + 'fecha_final' => now()->addDays($tarifa->dias), + 'valor' => $precio, + 'utilidad' => $tarifa->utilidad ?? 0, + 'tipo_pago' => 'saldo', + 'estado' => 'entregado', + 'vendedor_id' => $state['user_id'], + 'tarifa_id' => $tarifa->id, + 'cliente_id' => $state['user_id'], + 'nombre_cliente' => $user->name, + ]); + Historial_cuenta::create(['historial_id' => $historial->id, 'cuenta_id' => $cuenta->id]); + $cuenta->update(['estado' => 'ocupado']); + $saldo->update(['valor' => $nuevoSaldo]); + }); $text = "✅ *¡Compra exitosa!*\n\n"; $text .= "🎬 *{$tarifa->servicio->nombre}*\n"; @@ -920,29 +931,32 @@ class TelegramBotService return; } - $historial = Historiale::create([ - 'fecha_inicio' => now(), - 'fecha_final' => now()->addDays(30), - 'valor' => $precio, - 'utilidad' => $utilidad, - 'tipo_pago' => 'saldo', - 'estado' => 'entregado', - 'vendedor_id' => $user->id, - 'promocion_id' => $promoId, - 'cliente_id' => $user->id, - 'nombre_cliente' => $user->name, - ]); - - Historial_cuenta::create(['historial_id' => $historial->id, 'cuenta_id' => $cuenta->id]); - $cuenta->update(['estado' => 'ocupado']); + $dias = (int) ($promo->dias ?? 30); $nuevoSaldo = $saldo->valor - $precio; - $saldo->update(['valor' => $nuevoSaldo]); + + DB::transaction(function () use ($promo, $user, $saldo, $cuenta, $precio, $utilidad, $promoId, $dias, $nuevoSaldo) { + $historial = Historiale::create([ + 'fecha_inicio' => now(), + 'fecha_final' => now()->addDays($dias), + 'valor' => $precio, + 'utilidad' => $utilidad, + 'tipo_pago' => 'saldo', + 'estado' => 'entregado', + 'vendedor_id' => $user->id, + 'promocion_id' => $promoId, + 'cliente_id' => $user->id, + 'nombre_cliente' => $user->name, + ]); + Historial_cuenta::create(['historial_id' => $historial->id, 'cuenta_id' => $cuenta->id]); + $cuenta->update(['estado' => 'ocupado']); + $saldo->update(['valor' => $nuevoSaldo]); + }); $text = "✅ *¡Promo activada!*\n\n"; $text .= "🎬 *{$promo->nombre}*\n"; $text .= "📧 Email: `{$cuenta->correo}`\n"; $text .= "🔑 Password: `{$cuenta->password}`\n"; - $text .= "📅 Vence: " . now()->addDays(30)->format('d/m/Y') . "\n"; + $text .= "📅 Vence: " . now()->addDays($dias)->format('d/m/Y') . "\n"; $text .= "\nSaldo restante: *\$" . number_format($nuevoSaldo) . "*"; $this->send($chatId, $text); @@ -1123,7 +1137,7 @@ class TelegramBotService $historiales = Historiale::where('cliente_id', $state['user_id']) ->where('estado', 'entregado') ->where('fecha_final', '>=', now()) - ->with('tarifa.servicio') + ->with(['tarifa.servicio', 'cuentas']) ->orderBy('fecha_final', 'desc') ->limit(10) ->get();