Fix promotion listing: role-based filtering and correct pricing
- Filter promos by TarifaPromo.rol_id (same as services) - Fix visible filter: use string 'true' not boolean - Get price from Usuario_promo or TarifaPromo instead of Promociones.precio - Get utilidad from TarifaPromo for correct margin tracking - Applied same fixes to TelegramBotService promo flows Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
758b365b7f
commit
a21675b12c
@@ -12,6 +12,8 @@ use App\Models\Historiale;
|
||||
use App\Models\Historial_cuenta;
|
||||
use App\Models\Preferencial;
|
||||
use App\Models\Promociones;
|
||||
use App\Models\TarifaPromo;
|
||||
use App\Models\Usuario_promo;
|
||||
use App\Models\recarga;
|
||||
use App\Models\Role;
|
||||
use App\Models\Saldo;
|
||||
@@ -597,8 +599,15 @@ class TelegramBotService
|
||||
|
||||
private function listPromos(string $chatId): void
|
||||
{
|
||||
$promos = Promociones::where('visible', true)
|
||||
$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');
|
||||
|
||||
$promos = Promociones::where('visible', 'true')
|
||||
->where(fn ($q) => $q->whereNull('fecha_limite')->orWhere('fecha_limite', '>=', now()))
|
||||
->whereHas('tarifaPromo', fn ($q) => $q->where('rol_id', $rolId))
|
||||
->with(['tarifaPromo' => fn ($q) => $q->where('rol_id', $rolId)])
|
||||
->get();
|
||||
|
||||
if ($promos->isEmpty()) {
|
||||
@@ -611,7 +620,13 @@ class TelegramBotService
|
||||
$buttons = [];
|
||||
|
||||
foreach ($promos as $p) {
|
||||
$text .= "*{$p->nombre}* — \$" . number_format($p->precio) . "\n";
|
||||
$upric = isset($state['user_id'])
|
||||
? Usuario_promo::where('usuario_id', $state['user_id'])->where('promocion_id', $p->id)->first()
|
||||
: null;
|
||||
$tp = $p->tarifaPromo->first();
|
||||
$precio = $upric ? $upric->precio : ($tp ? $tp->precio : $p->precio);
|
||||
|
||||
$text .= "*{$p->nombre}* — \$" . number_format($precio) . "\n";
|
||||
if ($p->descripcion) {
|
||||
$text .= "{$p->descripcion}\n";
|
||||
}
|
||||
@@ -619,7 +634,7 @@ class TelegramBotService
|
||||
$text .= "Hasta: " . Carbon::parse($p->fecha_limite)->format('d/m/Y') . "\n";
|
||||
}
|
||||
$text .= "\n";
|
||||
$buttons[] = [['text' => ($p->nombre ?? 'Promo') . ' — $' . number_format($p->precio), 'callback_data' => 'promo_view|' . $p->id]];
|
||||
$buttons[] = [['text' => ($p->nombre ?? 'Promo') . ' — $' . number_format($precio), 'callback_data' => 'promo_view|' . $p->id]];
|
||||
}
|
||||
$buttons[] = [['text' => '🔙 Menú principal', 'callback_data' => 'menu']];
|
||||
|
||||
@@ -629,26 +644,36 @@ class TelegramBotService
|
||||
private function viewPromo(string $chatId, int $promoId): void
|
||||
{
|
||||
$state = $this->getState($chatId);
|
||||
$promo = Promociones::find($promoId);
|
||||
$rolId = isset($state['user_id'])
|
||||
? (User::find($state['user_id'])?->rol_id ?? Role::where('nombre', 'cliente')->value('id'))
|
||||
: Role::where('nombre', 'cliente')->value('id');
|
||||
|
||||
$promo = Promociones::with(['tarifaPromo' => fn ($q) => $q->where('rol_id', $rolId)])->find($promoId);
|
||||
|
||||
if (! $promo) {
|
||||
$this->send($chatId, "Promoción no encontrada.");
|
||||
return;
|
||||
}
|
||||
|
||||
$user = User::with('saldo')->find($state['user_id']);
|
||||
$saldo = $user->saldo?->valor ?? 0;
|
||||
$user = isset($state['user_id']) ? User::with('saldo')->find($state['user_id']) : null;
|
||||
$saldo = $user?->saldo?->valor ?? 0;
|
||||
|
||||
$upric = isset($state['user_id'])
|
||||
? Usuario_promo::where('usuario_id', $state['user_id'])->where('promocion_id', $promoId)->first()
|
||||
: null;
|
||||
$tp = $promo->tarifaPromo->first();
|
||||
$precio = $upric ? $upric->precio : ($tp ? $tp->precio : $promo->precio);
|
||||
|
||||
$buttons = [];
|
||||
if ($saldo >= $promo->precio) {
|
||||
$buttons[] = [['text' => "💳 Pagar con saldo (\$" . number_format($promo->precio) . ")", 'callback_data' => 'promo_saldo|' . $promoId]];
|
||||
if ($saldo >= $precio) {
|
||||
$buttons[] = [['text' => "💳 Pagar con saldo (\$" . number_format($precio) . ")", 'callback_data' => 'promo_saldo|' . $promoId]];
|
||||
}
|
||||
$buttons[] = [['text' => '🏦 MercadoPago', 'callback_data' => 'promo_mp|' . $promoId]];
|
||||
$buttons[] = [['text' => '🔙 Promociones', 'callback_data' => 'promo_list']];
|
||||
|
||||
$this->sendWithKeyboard(
|
||||
$chatId,
|
||||
"*{$promo->nombre}*\n\$" . number_format($promo->precio) . "\n\nElige cómo pagar:",
|
||||
"*{$promo->nombre}*\n\$" . number_format($precio) . "\n\nElige cómo pagar:",
|
||||
$buttons
|
||||
);
|
||||
}
|
||||
@@ -656,17 +681,29 @@ class TelegramBotService
|
||||
private function buyPromoSaldo(string $chatId, int $promoId): void
|
||||
{
|
||||
$state = $this->getState($chatId);
|
||||
$promo = Promociones::find($promoId);
|
||||
$user = User::with('saldo')->find($state['user_id']);
|
||||
$user = isset($state['user_id']) ? User::with('saldo')->find($state['user_id']) : null;
|
||||
|
||||
if (! $promo || ! $user) {
|
||||
if (! $user) {
|
||||
$this->send($chatId, "No se pudo procesar la compra.");
|
||||
return;
|
||||
}
|
||||
|
||||
$rolId = $user->rol_id;
|
||||
$promo = Promociones::with(['tarifaPromo' => fn ($q) => $q->where('rol_id', $rolId)])->find($promoId);
|
||||
|
||||
if (! $promo) {
|
||||
$this->send($chatId, "No se pudo procesar la compra.");
|
||||
return;
|
||||
}
|
||||
|
||||
$upric = Usuario_promo::where('usuario_id', $user->id)->where('promocion_id', $promoId)->first();
|
||||
$tp = $promo->tarifaPromo->first();
|
||||
$precio = $upric ? $upric->precio : ($tp ? $tp->precio : $promo->precio);
|
||||
$utilidad = $upric ? $upric->utilidad : ($tp ? $tp->utilidad : 0);
|
||||
|
||||
$saldo = $user->saldo;
|
||||
if (! $saldo || $saldo->valor < $promo->precio) {
|
||||
$this->send($chatId, "Saldo insuficiente (\$" . number_format($saldo?->valor ?? 0) . "). La promo cuesta \$" . number_format($promo->precio) . ".");
|
||||
if (! $saldo || $saldo->valor < $precio) {
|
||||
$this->send($chatId, "Saldo insuficiente (\$" . number_format($saldo?->valor ?? 0) . "). La promo cuesta \$" . number_format($precio) . ".");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -679,19 +716,19 @@ class TelegramBotService
|
||||
$historial = Historiale::create([
|
||||
'fecha_inicio' => now(),
|
||||
'fecha_final' => now()->addDays(30),
|
||||
'valor' => $promo->precio,
|
||||
'utilidad' => $promo->utilidad ?? 0,
|
||||
'valor' => $precio,
|
||||
'utilidad' => $utilidad,
|
||||
'tipo_pago' => 'saldo',
|
||||
'estado' => 'entregado',
|
||||
'vendedor_id' => $state['user_id'],
|
||||
'vendedor_id' => $user->id,
|
||||
'promocion_id' => $promoId,
|
||||
'cliente_id' => $state['user_id'],
|
||||
'cliente_id' => $user->id,
|
||||
'nombre_cliente' => $user->name,
|
||||
]);
|
||||
|
||||
Historial_cuenta::create(['historial_id' => $historial->id, 'cuenta_id' => $cuenta->id]);
|
||||
$cuenta->update(['estado' => 'ocupado']);
|
||||
$nuevoSaldo = $saldo->valor - $promo->precio;
|
||||
$nuevoSaldo = $saldo->valor - $precio;
|
||||
$saldo->update(['valor' => $nuevoSaldo]);
|
||||
|
||||
$text = "✅ *¡Promo activada!*\n\n";
|
||||
@@ -707,13 +744,24 @@ class TelegramBotService
|
||||
|
||||
private function buyPromoMP(string $chatId, int $promoId): void
|
||||
{
|
||||
$promo = Promociones::find($promoId);
|
||||
$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');
|
||||
|
||||
$promo = Promociones::with(['tarifaPromo' => fn ($q) => $q->where('rol_id', $rolId)])->find($promoId);
|
||||
if (! $promo) {
|
||||
return;
|
||||
}
|
||||
|
||||
$upric = isset($state['user_id'])
|
||||
? Usuario_promo::where('usuario_id', $state['user_id'])->where('promocion_id', $promoId)->first()
|
||||
: null;
|
||||
$tp = $promo->tarifaPromo->first();
|
||||
$precio = $upric ? $upric->precio : ($tp ? $tp->precio : $promo->precio);
|
||||
|
||||
$ref = 'PROMO-' . strtoupper(Str::random(10));
|
||||
$url = $this->createMPPreference($promo->nombre ?? 'Promocion streaming', (int) $promo->precio, $ref);
|
||||
$url = $this->createMPPreference($promo->nombre ?? 'Promocion streaming', (int) $precio, $ref);
|
||||
|
||||
if (! $url) {
|
||||
$this->send($chatId, "No se pudo generar el link de pago. Intenta de nuevo o contacta a un asesor.");
|
||||
@@ -722,7 +770,7 @@ class TelegramBotService
|
||||
|
||||
$this->sendWithKeyboard(
|
||||
$chatId,
|
||||
"🏦 *Pago con MercadoPago*\n\n{$promo->nombre} — \$" . number_format($promo->precio) . "\nRef: `{$ref}`\n\n[👉 Pagar ahora]({$url})\n\nDespués de pagar, envía la foto del comprobante aquí.",
|
||||
"🏦 *Pago con MercadoPago*\n\n{$promo->nombre} — \$" . number_format($precio) . "\nRef: `{$ref}`\n\n[👉 Pagar ahora]({$url})\n\nDespués de pagar, envía la foto del comprobante aquí.",
|
||||
[[['text' => '🔙 Menú principal', 'callback_data' => 'menu']]]
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user