up
This commit is contained in:
@@ -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();
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user