Files
2026-01-06 15:35:59 -05:00

172 lines
7.1 KiB
PHP

<?php
namespace App\Observers;
use App\Models\Compra;
use App\Models\Producto;
use App\Models\ProductVariant;
use App\Models\Bodega;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\DB;
class CompraObserver
{
/**
* Handle the Compra "created" event.
*/
public function created(Compra $compra): void
{
//
}
/**
* Handle the Compra "updated" event.
*/
public function updated(Compra $compra): void
{
// Solo procesar cuando el estado cambie a 'Recibida'
if ($compra->isDirty('estado') && $compra->estado === 'Recibida') {
Log::info("Procesando compra recibida", [
'compra_id' => $compra->id,
'detalles_count' => $compra->detalles->count()
]);
DB::beginTransaction();
try {
foreach ($compra->detalles as $detalle) {
Log::info("Procesando detalle de compra", [
'detalle_id' => $detalle->id,
'producto_id' => $detalle->producto_id,
'variante_id' => $detalle->variante_id,
'bodega_id' => $detalle->bodega_id,
'cantidad' => $detalle->cantidad
]);
if ($detalle->variante_id) {
// Manejo para variantes
$variante = ProductVariant::find($detalle->variante_id);
if ($variante && $detalle->bodega_id) {
// Actualizar stock en bodega para la variante
$existeRelacion = $variante->bodegas()
->where('bodega_id', $detalle->bodega_id)
->exists();
if ($existeRelacion) {
// Incrementar stock existente
$pivotData = $variante->bodegas()
->where('bodega_id', $detalle->bodega_id)
->first();
$nuevoStock = $pivotData->pivot->stock + $detalle->cantidad;
$variante->bodegas()->updateExistingPivot($detalle->bodega_id, [
'stock' => $nuevoStock
]);
} else {
// Crear nueva relación con stock
$variante->bodegas()->attach($detalle->bodega_id, [
'stock' => $detalle->cantidad
]);
}
Log::info("Stock actualizado para variante en bodega", [
'variante_id' => $variante->id,
'bodega_id' => $detalle->bodega_id,
'cantidad_agregada' => $detalle->cantidad
]);
} else {
// Fallback: incrementar stock directo de la variante si no hay bodega especificada
ProductVariant::where('id', $detalle->variante_id)
->increment('stock', $detalle->cantidad);
Log::info("Stock incrementado directamente en variante (sin bodega)", [
'variante_id' => $detalle->variante_id,
'cantidad' => $detalle->cantidad
]);
}
} else {
// Manejo para productos sin variantes
$producto = Producto::find($detalle->producto_id);
if ($producto && $detalle->bodega_id) {
// Actualizar stock en bodega para el producto
$existeRelacion = $producto->bodegas()
->where('bodega_id', $detalle->bodega_id)
->exists();
if ($existeRelacion) {
// Incrementar stock existente
$pivotData = $producto->bodegas()
->where('bodega_id', $detalle->bodega_id)
->first();
$nuevoStock = $pivotData->pivot->stock + $detalle->cantidad;
$producto->bodegas()->updateExistingPivot($detalle->bodega_id, [
'stock' => $nuevoStock
]);
} else {
// Crear nueva relación con stock
$producto->bodegas()->attach($detalle->bodega_id, [
'stock' => $detalle->cantidad
]);
}
Log::info("Stock actualizado para producto en bodega", [
'producto_id' => $producto->id,
'bodega_id' => $detalle->bodega_id,
'cantidad_agregada' => $detalle->cantidad
]);
} else {
// Fallback: incrementar stock directo del producto si no hay bodega especificada
Producto::where('id', $detalle->producto_id)
->increment('stock', $detalle->cantidad);
Log::info("Stock incrementado directamente en producto (sin bodega)", [
'producto_id' => $detalle->producto_id,
'cantidad' => $detalle->cantidad
]);
}
}
}
DB::commit();
Log::info("Compra procesada exitosamente", ['compra_id' => $compra->id]);
} catch (\Exception $e) {
DB::rollback();
Log::error("Error al procesar compra recibida", [
'compra_id' => $compra->id,
'error' => $e->getMessage(),
'trace' => $e->getTraceAsString()
]);
throw $e;
}
}
}
/**
* Handle the Compra "deleted" event.
*/
public function deleted(Compra $compra): void
{
//
}
/**
* Handle the Compra "restored" event.
*/
public function restored(Compra $compra): void
{
//
}
/**
* Handle the Compra "force deleted" event.
*/
public function forceDeleted(Compra $compra): void
{
//
}
}