This commit is contained in:
Lizandro Guarnizo
2026-04-18 14:13:24 -05:00
parent 03207775af
commit d11423c379
2 changed files with 51 additions and 7 deletions
+19 -2
View File
@@ -329,11 +329,28 @@ class ShowPromociones extends Component
}
if ($cuenta) {
$perfil = Historial_cuenta::where('cuenta_id', $cuenta->id)->max('perfil') ?? 0;
// Bloquear la fila y re-verificar conteo real antes de insertar (protección race condition)
$cuentaLocked = Cuentas::where('id', $cuenta->id)->lockForUpdate()->first();
$perfil = Historial_cuenta::where('cuenta_id', $cuentaLocked->id)->max('perfil') ?? 0;
$perfilesOcupados = Historial_cuenta::where('cuenta_id', $cuentaLocked->id)
->whereHas('historial', fn($q) => $q->where('estado', 'activo'))
->count();
$maxPerfiles = ($cuentaLocked->estado === 'pendiente')
? $pantalla_servicio_completa
: $pantalla_servicio;
if (($perfilesOcupados + (int) $pantallas_tarifa) > $maxPerfiles) {
$this->f[] = $servicio_id;
$this->alert('warning', 'No hay perfiles disponibles de ' . $tarifa->servicio->nombre . ', intenta nuevamente.', ['position' => 'top']);
continue;
}
for ($y = 0; $y < (int) $pantallas_tarifa; $y++) {
$historial_cuenta = new Historial_cuenta();
$historial_cuenta->historial_id = $historial->id;
$historial_cuenta->cuenta_id = $cuenta->id;
$historial_cuenta->cuenta_id = $cuentaLocked->id;
$historial_cuenta->perfil = (int) $perfil + (int) $y + 1;
$historial_cuenta->save();
+32 -5
View File
@@ -394,19 +394,46 @@ class ShowServicios extends Component
$esta_error = false;
$cuentasMostar = '';
//$perfil = $cuenta[$h]->historiales_count;
$perfil = Historial_cuenta::where('cuenta_id', $cuenta[$h]->id)->max('perfil') ?? 0;
// Bloquear la fila de la cuenta para leer el conteo real dentro de la transacción
$cuentaLocked = Cuentas::where('id', $cuenta[$h]->id)->lockForUpdate()->first();
$perfil = Historial_cuenta::where('cuenta_id', $cuentaLocked->id)->max('perfil') ?? 0;
// Verificar que aún hay espacio real ANTES de insertar (protección contra race condition)
$perfilesOcupados = Historial_cuenta::where('cuenta_id', $cuentaLocked->id)
->whereHas('historial', fn($q) => $q->where('estado', 'activo'))
->count();
$maxPerfiles = ($cuentaLocked->estado === 'pendiente')
? ($cuentaLocked->servicio->completa ?? $pantallas)
: ($cuentaLocked->servicio->pantallas ?? $pantallas);
if (($perfilesOcupados + (int) $pantallas) > $maxPerfiles) {
$esta_error = true;
$historial->update(['estado' => 'cancelado']);
Historial_cuenta::where('historial_id', $historial->id)->delete();
$logsGeneral = new Log_general();
$logsGeneral->user_id = Auth::user()->id;
$logsGeneral->detalle = 'El usuario ' . Auth::user()->name . ' - ' . Auth::user()->email . ' Tuvo error de concurrencia: la cuenta ' . $cuentaLocked->correo . ' ya estaba llena al momento de insertar el perfil. Compra cancelada automáticamente. Servicio: ' . $servicioNombre;
$logsGeneral->tipo = 'compra_error';
$logsGeneral->historial_id = $historial->id;
$logsGeneral->save();
DB::rollBack();
$this->alert('warning', 'No hay perfiles disponibles, intenta nuevamente!', [
'position' => 'top'
]);
return;
}
for ($y = 0; $y < (int) $pantallas; $y++) {
$historial_cuenta = new Historial_cuenta;
$historial_cuenta->cuenta_id = $cuenta[$h]->id;
$historial_cuenta->cuenta_id = $cuentaLocked->id;
$historial_cuenta->historial_id = $historial->id;
$historial_cuenta->perfil = (int) $perfil + (int) $y + 1;
$historial_cuenta->save();
if ($cuenta[$h]->correo != $cuentasMostar) {
$cuentasMostar .= $cuenta[$h]->correo . ' ';
if ($cuentaLocked->correo != $cuentasMostar) {
$cuentasMostar .= $cuentaLocked->correo . ' ';
}
}
} else {